Thread: Are the musical notes valid in this program?

  1. #1
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288

    Are the musical notes valid in this program?

    My post here was similar to this : Is this a good way of writing this program?

    I wanted to start fresh with my new code though and a better title.

    Basically, I took what I learned from my questions in that thread and managed to build a list of musical notes( octaves, frequencies, sharp symbols, basically everything ) with the help of the structures Anduril wanted me to use and the suggestions from others.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    
    
    #define MAX_NOTES 88  /* 88 keys on a standard piano */
    
    
    #define WIN_32_LEAN_AND_MEAN /* Trims all the lard from Windows */
    #include <windows.h>
    
    
    /* *****************************
    * PIANO_KEY_FREQUENCY(n) - macro
    *
    * - Takes 1 argument ( n )
    * - Argument can be an expression
    * - It tests the argument to make
    * sure it is always above 0 and
    * below 89.
    * - If the parameter is not in a
    * valid range, the macro evalutates
    * to 0.
    * - If the parameter is in a valid range
    * it uses a formula shown beside it that
    * calculates the frequency of that key
    * number.
    ***************************** */
    
    
    #define FREQUENCY(n) ((pow((pow(2.00, (1.00/12.00))), ((n) - 49.00)) * 440.00)) /* f(n) = ((2^1/12)^n-49) * 440Hz */
    #define PIANO_KEY_FREQUENCY(n) ( n > 0 && n < 89 ? (FREQUENCY(n)) : (0) ) /* Validates user input */
    
    
    /* *************************** */
    
    
    typedef struct note_info note_info;
    
    
    struct note_info {
        char note;
        unsigned int octave;
        unsigned int freq;
    };
    
    
    typedef struct sound_element sound_element;
    
    
    struct sound_element {
        unsigned int freq;  /* 0 freq means rest */
        unsigned int duration_ms;
        sound_element *next;
    };
    
    
    unsigned int GetNextOctave( )
    {
        static unsigned int octave = 0;
        static unsigned int interval = 0;
        static unsigned int interval_2 = 0;
    
    
        if (octave < 7 )
        {
            if ( octave == 0 )
            {
                if ( interval++ > 2 )
                    return ++octave;
            } else {
    
    
                if ( interval++ == 15 )
                {
                        interval = 4;
                        return ++octave;
                }
            }
        }
    
    
        if ( octave == 7 )
        {
            if ( interval_2++ > 10 )
                return ++octave;
        }
    
    
        return octave;
    }
    
    
    unsigned int GetNextNote( )
    {
        static unsigned int note = 'A';
        unsigned int temp = 0;
        static unsigned int counter = 0;
    
    
        switch (counter++)
        {
            case 0:
                return note;
                break;
            case 1:
            case 4:
            case 6:
            case 9:
                return tolower(note);
                break;
            case 2:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
                return toupper((++note));
                break;
            case 11:
                counter = 0;
                temp = note;
                note = 'A';
    
    
                return tolower(temp);
                break;
        }
    
    
        return note;
    }
    
    
    int main( )
    {
        int ctr;
    
    
        note_info notes[MAX_NOTES];
    
    
        for ( ctr = 0; ctr < MAX_NOTES; ctr++ )
        {
            notes[ctr].freq = PIANO_KEY_FREQUENCY(ctr + 1);
            notes[ctr].octave = GetNextOctave();
            notes[ctr].note = GetNextNote();
        }
    
    
        for ( ctr = 0; ctr < MAX_NOTES; ctr++ )
        {
            fprintf(stdout, "%c%d%c, frequency : %d\n", toupper(notes[ctr].note), notes[ctr].octave, islower(notes[ctr].note) ? '#' : ' ', notes[ctr].freq );
        }
    
    
        return 0;
    }
    Code:
    Output :
    
    A0 , frequency : 27
    A0#, frequency : 29
    B0 , frequency : 30
    C1 , frequency : 32
    C1#, frequency : 34
    D1 , frequency : 36
    D1#, frequency : 38
    E1 , frequency : 41
    F1 , frequency : 43
    F1#, frequency : 46
    G1 , frequency : 48
    G1#, frequency : 51
    A1 , frequency : 54
    A1#, frequency : 58
    B1 , frequency : 61
    C2 , frequency : 65
    C2#, frequency : 69
    D2 , frequency : 73
    D2#, frequency : 77
    E2 , frequency : 82
    F2 , frequency : 87
    F2#, frequency : 92
    G2 , frequency : 97
    G2#, frequency : 103
    A2 , frequency : 109
    A2#, frequency : 116
    B2 , frequency : 123
    C3 , frequency : 130
    C3#, frequency : 138
    D3 , frequency : 146
    D3#, frequency : 155
    E3 , frequency : 164
    F3 , frequency : 174
    F3#, frequency : 184
    G3 , frequency : 195
    G3#, frequency : 207
    A3 , frequency : 219
    A3#, frequency : 233
    B3 , frequency : 246
    C4 , frequency : 261
    C4#, frequency : 277
    D4 , frequency : 293
    D4#, frequency : 311
    E4 , frequency : 329
    F4 , frequency : 349
    F4#, frequency : 369
    G4 , frequency : 391
    G4#, frequency : 415
    A4 , frequency : 440
    A4#, frequency : 466
    B4 , frequency : 493
    C5 , frequency : 523
    C5#, frequency : 554
    D5 , frequency : 587
    D5#, frequency : 622
    E5 , frequency : 659
    F5 , frequency : 698
    F5#, frequency : 739
    G5 , frequency : 783
    G5#, frequency : 830
    A5 , frequency : 880
    A5#, frequency : 932
    B5 , frequency : 987
    C6 , frequency : 1046
    C6#, frequency : 1108
    D6 , frequency : 1174
    D6#, frequency : 1244
    E6 , frequency : 1318
    F6 , frequency : 1396
    F6#, frequency : 1479
    G6 , frequency : 1567
    G6#, frequency : 1661
    A6 , frequency : 1760
    A6#, frequency : 1864
    B6 , frequency : 1975
    C7 , frequency : 2093
    C7#, frequency : 2217
    D7 , frequency : 2349
    D7#, frequency : 2489
    E7 , frequency : 2637
    F7 , frequency : 2793
    F7#, frequency : 2959
    G7 , frequency : 3135
    G7#, frequency : 3322
    A7 , frequency : 3520
    A7#, frequency : 3729
    B7 , frequency : 3951
    C8 , frequency : 4186
    My main question is, did I label this list right? I already know the frequencies are correct( they are rounded, but they should be close enough to the value ), but I wasn't so sure about the note labels. Obviously though, I'm not done with this program and I will be adding most of the functions Anduril suggested to take a text file and convert it into music. I just wanted to make sure I had everything correct before moving on. I probably didn't do the GetNextOctave() and GetNextNote() functions very efficiently so feel free to make suggestions on those functions also.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You can do this with a lot less code. I added .5 to your calculation to round up.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    #define NUM_NOTES 88
    #define OCTAVE(n) (((n)+9)/12)
    #define NOTENAME(n) (name[((n)+9)%12])
    #define FREQUENCY(n) ( pow( pow(2.,1./12.), (n)-49. ) * 440. + .5)
    
    char*name[12]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
    
    int main() {
        int n;
        for (n = 0; n < NUM_NOTES; n++)
            printf("%-2s%d  %d\n", NOTENAME(n), OCTAVE(n), (int)FREQUENCY(n+1));
        return 0;
    }

  4. #4
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by oogabooga View Post
    You can do this with a lot less code. I added .5 to your calculation to round up.
    Code:
    #include <stdio.h>
    #include <math.h>
    
    #define NUM_NOTES 88
    #define OCTAVE(n) (((n)+9)/12)
    #define NOTENAME(n) (name[((n)+9)%12])
    #define FREQUENCY(n) ( pow( pow(2.,1./12.), (n)-49. ) * 440. + .5)
    
    char*name[12]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
    
    int main() {
        int n;
        for (n = 0; n < NUM_NOTES; n++)
            printf("%-2s%d  %d\n", NOTENAME(n), OCTAVE(n), (int)FREQUENCY(n+1));
        return 0;
    }
    Thank you. I thought there was some way to do it mathematically like that since I noticed a pattern, I just didn't know how to make a formula for it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. date valid program
    By tiger6425 in forum C Programming
    Replies: 4
    Last Post: 09-02-2010, 10:03 PM
  2. Socket file descriptor valid and then not valid
    By Florian in forum C Programming
    Replies: 3
    Last Post: 05-22-2010, 08:23 AM
  3. Do you play a musical instrument?
    By dbaryl in forum A Brief History of Cprogramming.com
    Replies: 39
    Last Post: 08-18-2002, 10:40 PM
  4. musical notes using sound()
    By lambs4 in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 02-09-2002, 08:48 PM