Thread: an uber-simple array/function question for a c rookie!

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    6

    an uber-simple array/function question for a c rookie!

    Hi all,

    i'm trying to write a basic synthesizer program that can stores a sequence of midi notes and their associated channel/velocity data. at the moment i have this which can take the data and use that to turn an oscillator on, however i want to be able to store a sequence of notes in an array so i can record/playback the sequence.


    i am having difficulty in reading the data into an array, so far i have this (excluding the note synthesis code) to set the array element value to the note number but the osc is only playing 8 notes. from the decoder is taking the note-off message i.e. me releasing the key as the next note?:

    Code:
    int main()
    {
    	int notes[16];
    	int index, note, velocity;
    	
    	for(index = 0; index < 16; index ++)
    	{
    		note = aserveGetNote();
    		velocity = aserveGetVelocity();
    		notes[index] = note;
    		printf("Note %d\n", index);
    		processNote(note);
    	}
    	return 0;
    }
    is there anyone that can help/ point me in the right direction so i can get my sequencer up and running?. sorry for the long first post!

    any and all help is greatly appreciated
    Last edited by variable83; 12-07-2009 at 02:55 AM.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    change this line:

    Code:
    else(velocity == 0)
    
    //to
    
    else if(velocity == 0)
    how many states can velocity have? If it can only be > 0 or 0, then you can eliminate the code in blue.
    If the velocity can be less than 0, then you may need to add an else onto this if statement, to handle
    that state, as well.
    Last edited by Adak; 12-06-2009 at 11:14 AM.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Is it possible for each note to have a unique velocity and channel? If so, an array of structures would be better:
    Code:
    struct midisoundnotething
    {
        int note;
        int velocity;
        int channel;
        
    } notes[ ARRAYSIZE ];
    But you don't actually do anything with your entire music chunk (your array) in the fist example anyway, so I'm not sure you even need it there at all.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Adak View Post
    change this line:

    Code:
    else(velocity == 0)
    
    //to
    
    else(velocity = 0)
    How about no. You don't do:
    Code:
    if( x == y )
    {
    }
    else ( )
    {
    }
    You do:
    Code:
    if( x == y )
    {
    }
    else
    {
    }
    The whole parenthesis segment is wrong when combine with that else

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    6
    Quote Originally Posted by quzah View Post
    Is it possible for each note to have a unique velocity and channel? If so, an array of structures would be better:
    Code:
    struct midisoundnotething
    {
        int note;
        int velocity;
        int channel;
        
    } notes[ ARRAYSIZE ];
    But you don't actually do anything with your entire music chunk (your array) in the fist example anyway, so I'm not sure you even need it there at all.


    Quzah.
    hello mate,

    Thanks for the quick respsonse. with the second piece of code i posted, all i really want to do is to read a sequence of note numbers into (for example) a 32 element array, which i then can enclose in another loop so i can play the sequence of notes entered.

    (on second thought, yes, the first bit of code is not needed at all)


    cheers

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You will also need timing information, such as when a note happens and the duration in your sequence. Unless it's some kind of pattern sequencer with default "grid" values such as 16th or 8th notes for example.
    Last edited by Subsonics; 12-06-2009 at 11:27 AM.

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    6
    Quote Originally Posted by Adak View Post
    change this line:

    Code:
    else(velocity == 0)
    
    //to
    
    else if(velocity == 0)
    how many states can velocity have? If it can only be > 0 or 0, then you can eliminate the code in blue.
    If the velocity can be less than 0, then you may need to add an else onto this if statement, to handle
    that state, as well.
    velocity in midi can be 0-127. a velocity of '0' is treated as a 'note-off' msg. at the mo my synthesizer is looking like this:

    Code:
    #include <stdio.h>
    #include "aservelibs/aservelib.h"
    #include <math.h>
    
    // function declarations
    float mtof(int note);
    float mtoamp(int velocity);
    
    
    void processNote(int note);
    
    
    int main()
    {
    	int notes[16];
    	int index, note, velocity;
    	
    	for(index = 0; index < 16; index ++)
    	{
    		note = aserveGetNote();
    		velocity = aserveGetVelocity();
    		notes[index] = note;
    		printf("Note %d\n", index);
    		processNote(note);
    	}
    	return 0;
    }
    
    void processNote(int note)
    {
    	static int lastnote = -1;
    	int velocity;
    	float frequency, amp;
    	
    	if(velocity > 0)
    	{
    		frequency = mtof(note);
    		amp = mtoamp(velocity);
    		printf("Note %3d = %3.2fHz\n", note, frequency);
    		aserveOscillator(0, frequency, amp, 0); 
    	}
    	else if ( velocity == 0)
    	{
    		aserveOscillator(0, 0.0, 0.0, 0);
    	}
    }
    	
    
    float mtof(int note)
    {
    	float frequency = 440.0 * pow(2.0, (note - 69.0) / 12.0);
    	return frequency;
    }
    float mtoamp(int velocity) // note velocity to amplitude conversion
    {
    	float amp = velocity * (1.0 / 127);
    	return amp;
    }
    its turning the osc on and off fine, but only actually synthesizing 8 notes instead of the 16.

    v.

  8. #8
    Registered User
    Join Date
    Dec 2009
    Posts
    6
    ignore my last comments. its suddenly decided to start working. Awesome. am i right in thinking that code in my last post has assigned the array elements to the note numbers of the sequence? how wold i get the sequence to play thru again.?


    thanks for all the help. you guys are legends!

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    If you have assigned them in order, then simply loop back through the array and use what's stored there to pass along to whatever you use to play them.
    Code:
    for( x = 0; x < WHATEVER; x++ )
        play( array[ x ] );

    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If velocity can't be less than zero, then you can delete the if(velocity == 0) in blue, above.

    An else is all that you need there.

  11. #11
    Registered User
    Join Date
    Dec 2009
    Posts
    6
    Quote Originally Posted by quzah View Post
    If you have assigned them in order, then simply loop back through the array and use what's stored there to pass along to whatever you use to play them.
    Code:
    for( x = 0; x < WHATEVER; x++ )
        play( array[ x ] );

    Quzah.
    so i would put the loop in after the original? how would i get the note data back out of the array to my synth? sorry if i'm being a tool. i'm having a complete mental block today!

    Code:
    int main()
    {
    	int notes[16];
    	int count, note, velocity;
    	
    	for(count = 0; count < 16; count ++)
    	{
    		note = aserveGetNote();
    		velocity = aserveGetVelocity();
    		notes[count] = note;
    		printf("Note %d\n", count);
    		processNote(note);
    	}
    	
    -->	for(count = 0; count < 16; count ++)
    	{
    		//read note numbers from notes[]? then pass to osc to play
    	}

  12. #12
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You must be using a MIDI library of some sort?, so you'll need to pass the curent struct inside your loop the the "play()" function of that library I guess. But it seems to me that you will also need some global timing like a global BPM or something. Then from that value calculate the duration of a 8th note and put in a micro sleep in each iteration of the loop. It would probably make sense to make the loop into a circular buffer that keeps playing until you hit stop. One way of doing that is to use a unsigned char as the index then update it with +=16 or something, the index will then overflow each 16th iteration.
    Last edited by Subsonics; 12-06-2009 at 01:02 PM.

  13. #13
    Registered User
    Join Date
    Dec 2009
    Posts
    6
    Quote Originally Posted by Subsonics View Post
    You must be using a MIDI library of some sort?, so you'll need to pass the curent struct inside your loop the the "play()" function of that library I guess. But it seems to me that you will also need some global timing like a global BPM or something. Then from that value calculate the duration of a 8th note and put in a micro sleep in each iteration of the loop. It would probably make sense to make the loop into a circular buffer that keeps playing until you hit stop. One way of doing that is to use a unsigned char as the index then update it with +=16 or something, the index will then overflow each 16th iteration.
    yeah i'm using "aservelibs/aservelib.h" which deals with all the timings and bpms etc. i just need a bit of help with the contents of the for loop i need to count back thru the notes that i stored in the array and pass them back to the oscillator. eventually i'm going to write a couple of functions that will play the sequence stored in notes[] for backwards, maybe randomize the order etc.

  14. #14
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Ok, I see. I'm not familiar with servelib, but you would still pass the struct at index "count" to a "send" or "play" function of some sort in each iteration of the loop. What these functions are or how they are called I don't know. It should be in the documentation of servelib i presume.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple question regarding variables
    By Flakster in forum C++ Programming
    Replies: 10
    Last Post: 05-18-2005, 08:10 PM
  2. Simple class question
    By 99atlantic in forum C++ Programming
    Replies: 6
    Last Post: 04-20-2005, 11:41 PM
  3. Simple question about pausing program
    By Noid in forum C Programming
    Replies: 14
    Last Post: 04-02-2005, 09:46 AM
  4. simple question.
    By InvariantLoop in forum Windows Programming
    Replies: 4
    Last Post: 01-31-2005, 12:15 PM
  5. A Simple Question
    By Unregistered in forum Windows Programming
    Replies: 1
    Last Post: 10-26-2001, 05:23 PM

Tags for this Thread