Thread: random music in C

  1. #1
    Registered User
    Join Date
    Apr 2013
    Posts
    9

    random music in C

    Hey there.

    I'm very very new to C and am having some trouble with a program I'm writing. The program is meant to improvise around a scale and do a different sequence everytime. However every time I start the program it does the exact same sequence despite it using random numbers.

    Code:
    #include "stdlib.h"
    #include "midi_lib.h"
     
    int main(void)
    {
    
     /* Declare integer variables for specifying a note */
     int pitch, channel, velocity, offset, key;
     int i, bar_duration, note_duration;
     int velocity_reduction = 32;
        int program_quit=0;
        int scale_note;
     
       
        int major_scale[8] = {0, 2, 4, 5, 7, 9, 11, 12};
        int minor_scale[8] = {0, 2, 3, 5, 7, 8, 10, 12};
        int mixolydian_scale[8] = {0, 2, 4, 5, 7, 9, 10, 12};
    
     key = 60;  /* middle C */
     channel = 1;
     velocity = 64; /* mediu loudness */
     bar_duration = 4*400; /* the first four notes take this time */
        midi_start();
    
        while (!program_quit)
            {
                midi_note(key + mixolydian_scale[(rand() % (8+1-0))+0], 1, 64);
                pause((rand() % (500+1-125)) + 125);
                midi_note(key + mixolydian_scale[(rand() % (8+1-0))+0], 1, 0);
              
            }
    
        midi_close();
     return 0;
    }
    any help and advice would be much appreciated.

    Cheers in advance

    dogma93
    Last edited by dogma93; 04-27-2013 at 12:17 PM.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    You need to seed the random generator. Lookup the use of srand().
    Kurt

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    awesome that worked thank you.

    As a side question is there any way to make the note duration more musical? As it stands I've got it to play for a random amount of time but this is very inconsistant just sounds disordered.

    Again any advice would be much appreciated

    Cheers
    Last edited by dogma93; 04-27-2013 at 12:52 PM.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Initialize an array with some durations and randomly pick any of them.
    Kurt

  5. #5
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    that worked but it seems that the sample rate is off or something as the sound seems to stutter from time to time. The code also ocationalyl plays some chords and I don't know why.


    Code:
      int note_held[4] = {1000, 750, 500, 250};
        midi_start();
    
    
     while (!program_quit)
            {
                midi_note(key + mixolydian_scale[(rand() % (8+1-0))+0], 65, ((rand() % (124+1-64))+64));
                pause(note_held[((rand() % (4+1-0)) + 0)]);
                midi_note(key + mixolydian_scale[(rand() % (8+1-0))+0], 65, 0);
                srand (time(NULL));
            }
    Last edited by dogma93; 04-27-2013 at 01:19 PM.

  6. #6
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    pause(note_held[((rand() % (4+1-0)) + 0)]);
    needs to be
    Code:
    pause(note_held[(rand() % 4)]);
    this gives indexes from 0 to 3
    Kurt

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    I assume you only want one note ever playing at a time.

    You are selecting a new random note value for the "note off" message, a value that will likely be different than
    the value used for the "note on" message. So you are not turning off each note that you play until it's value
    randomly comes up again in the "note off" statement.

    It should look more like this, using the same note value for both "note on" and "note off":

    Code:
    while (!program_quit)
            {
                note = key + mixolydian_scale[(rand() % (8+1-0))+0];
                midi_note(note, 1, 64);
                pause((rand() % (500+1-125)) + 125);
                midi_note(note, 1, 0);
            }

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    Thankyou that worked perfectly!

    The program does tend to pick the same note in a row alot of the time which makes it sound very robotic. Any ideas on how to make it sound more natural?

    Cheers

  9. #9
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    You could make a function randomNote() that remembers the last index returned and selects another if rand() returns the previous index
    Kurt

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    srand should only be called once, at the start of your program, never inside a loop.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    Moving srand out of the loop and to the start of the program seems to have fixed it. It now doesn't repeat and it now seems trully random. Thank you !

  12. #12
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    Any idea how i would be able to change the instrument choice? As it is the program can only play a piano but I want to make it so the user can change the intrument choice. I'd also like to be able to control the scale but am confused how to change the selected array.

  13. #13
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    You should be able to send a "patch change" message to select an instrument. It would likely
    be referred to as a "patch change" or "program change" and you will want to use the same
    channel number as used for playing notes. If you are using the MS wavetable synth, (or most
    software synths for that matter), the instrument asignments will follow the General Midi (GM)
    standard.

    Is there a reference for the midi_lib.h functions online somewhere? I'll take a look.

  14. #14
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    One way to handle the various scales is to use a multidimensional array.
    Use the first index for the scale, and the second index for the note within the scale.

    Code:
        int scale[3][8] = { {0, 2, 4, 5, 7, 9, 11, 12}, {0, 2, 3, 5, 7, 8, 10, 12}, {0, 2, 4, 5, 7, 9, 10, 12} };
    The second note in the major scale would be scale[0][1],
    the 3rd note in the mixolydian scale would be scale[2][2], etc

  15. #15
    Registered User
    Join Date
    Apr 2013
    Posts
    9
    Hey there I'm trying to use switch statements in my code so that the key can be changed in real time using keyboard presses. However when I use a while loop around the switch statements nothing happens at all. Any ideas on what I've done wrong?

    Code:
     int letter_entered;
    
    letter_entered = getch();
    
    while(!program_quit)
    {
        switch (letter_entered)
        {
            case 'a': case 'A':
            key = 57;
            break;
            case 'b': case 'B':
            key = 59;
            break;
            case 'v': case 'V':
            key = 58;
            break;
            case 'h': case 'H':
            key = 56;
            break;
            case 'g': case 'G':
            key = 55;
            break;
            case 't': case 'T':
            key = 54;
            break;
            case 'f': case 'F':
            key = 53;
            break;
            case 'e': case 'E':
            key = 52;
            break;
            case 'w': case 'W':
            key = 51;
            break;
            case 'd': case 'D':
            key = 50;
            break;
            case 's': case 'S':
            key = 51;
            break;
            case 'c': case 'C':
            key = 60;
            break;
            default:
            printf ("that was an invalid input");
            break;
        }
    }
    Last edited by dogma93; 04-30-2013 at 08:53 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need a random number generator thats not compleatly random
    By thedodgeruk in forum C++ Programming
    Replies: 1
    Last Post: 06-05-2011, 06:48 AM
  2. Replies: 4
    Last Post: 11-16-2004, 07:29 AM
  3. take out music in mp3
    By Klinerr1 in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 03-19-2004, 11:19 AM
  4. Replies: 2
    Last Post: 12-25-2003, 01:31 AM
  5. Replies: 1
    Last Post: 12-14-2002, 01:51 AM