0

I'm certain my code is waaaay too long for what they are asking me to do, but I'm not sure how to change the thought process. In any case, my check comes back with huge numbers, so the math is wrong somewhere, and my first note on line 1 is d4@1/8, which I know is right from the music, but it's saying it's wrong. Can someone nudge me in the right direction? Am I making this harder than it needs to be?

  :( bday.txt is correct
Incorrect note on line 1
  :( note A4 has frequency 440
>     expected "440", not "675840" 
  :( note A6 has frequency 1760
>     expected "1760", not "704000" 
  :( note A#5 has frequency 932
>     expected "932", not "344960" 
  :( note Ab3 has frequency 208
>     expected "208", not "10588160" 
  :( note C3 has frequency 131
>     expected "131", not "41360" 
  :( note Bb5 has frequency 932
>     expected "932", not "43120" 
  :( produces all correct notes for octaves 3-5
>     Incorrect frequency for C3, should be 131, not 41360

Code:

// Calculates frequency (in Hz) of a note
int frequency(string note)
{
    char * scale[12] = {
    "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
    int oct = note[strlen(note) - 1]; //this should get me the last number in the string note, the octave
    int hertz = 440;
    int tothertz;
    int move = (strcmp(&note[0], scale[9])); //spaces from A
    float expon = ((move + 1) / 12);
    float step = pow(2, expon); //hertz divided by 2 to the move'th power divided by 12.
    int multtothertz = round(hertz * step); //hertz divided by (2 to the move'th power divided by 12).
    int divtothertz = round(hertz / step);

    if (strchr(&note[1], '#') == 0)  //if the character in index 1 match #, add one to the move.
    {
        move = move + 1;
    }
    else if (strchr(&note[1], 'b') == 0) // if the char index 1 matches b, subtract 1 from the move.
    {
        move = move - 1;
    }

    if (move == 0) //if the move is zero spaces away from A..
    {
        if (oct == 4) //and if the octave equals 4
        {
            tothertz = 440; // just return 440
        }
        else if (oct > 4)  //if the octave is greater than 4, take the oct - 4, which is hte spaces away from 4 it should be
        {
            tothertz = ((oct - 4) * 2) * hertz; // and multiply by 2 (which is one octave jump)
        }
        else//if (oct < 4) //if octave is less than 4,
        {
            tothertz = (hertz / (2 * (4 - oct)));  // divide hertz by number of octaves * 2.
        }
        return tothertz;
    }
    else if (move >= 1 && oct > 4) //if the move is greater than/equal to one and octave is greater than 4
    {
        tothertz = ((oct - 4) * 2) * multtothertz; //take oct - 4 (how many octs to move) and multiply by 2 , then mult ((hertz * 2^move/12))
        return tothertz;
    }
    else if (move >= 1 && oct < 4) //if move is great/equal than 1 and octave is less than 4
    {
        tothertz = divtothertz / (2 * (4 - oct)); //(hertz / 2^move/12) /  (2 * (4-oct)) to get how many times to divide down octaves
        return tothertz;
    }
    else if (move <= 1 && oct < 4) //if move is less/equal 1, and oct is less than 4
    {
        for (int n = 0; n > move; n--) // counter to count from oct to 0
            {
                tothertz = (divtothertz / (2 * (4 - oct))); //((hertz / 2^move/12) divided by (2 * (4-oct)) to get how many times to divide down octaves
            }
        return tothertz;
    }
    else //if (move <= 1 && oct > 4) // if move is less/equal to 1 and oct is greater than 4
    {
        for (int n = 0; n < move; n++)
        {
            tothertz = ((oct - 4) * 2) * multtothertz; //oct-4 is how many octaves, time 2 per each octave.  All that times (hertz * 2^move/12)
        }
        return tothertz;
    }

}

// Determines whether a string represents a rest
bool is_rest(string s)
{
    if ((strcmp(s, "")) == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
0

First, you're thinking too complicated. Functions like strcmp and strchr work differently than what you think, don't exactly match our problem (remember a C string is defined as a memory address where characters are stored, and the actual string runs to the first null byte).

Best to switch to simpler code, for example, if (note[1] == '#') instead of if (strchr(&note[1], '#') == &note[1]).

Also, you seem to confuse digit characters and the meaning you associate with them. '4' is an 8-bit integer of value 52 (look it up in the ASCII table if you want), not 4. You could subtract a digit, like int oct = note[strlen(note) - 1] - '0';, to have the value represent an octave as a number.

((oct - 4) * 2) makes no sense to me, given how power works. pow(2, oct - 4) is 2 * 2 * ... * 2 with oct - 2 times the 2, but * in between, not +. pow would likely be your last step in computing the frequency (maybe before applying the octave in a loop, but I'd interpret an octave as 12 semitones and throw them all into one number, the number of semitones relative to A4).

2
  • I completely redid my code and it sort of works now, except the octaves are still wonky. For A4, it works, and for A#5 it works. everything else is wrong. It's odd b/c for C3, it ends up with the default value for some reason, while others are just a little bit off.
    – stephanie
    Apr 27 '18 at 17:45
  • I figured it out. For some reason the code just dies before it gets done. I think this is a different issue. Thank you for your guidance! It got me thinking outside of my box!
    – stephanie
    Apr 27 '18 at 18:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .