0

Can someone please look at my helpers.c code for pset3? I worked a lot on this and I am stuck. 'wavelength' (which is frequency) doesn't calculate correctly within octave 4, and my code to add or subtract for other octaves isn't working.

// Helper functions for music
#include <cs50.h>
#include "helpers.h"
#include <math.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

// Converts a fraction formatted as X/Y to eighths
int duration(string fraction)
{
    // TODO
    //convert divisor to an integer
    int numerator = fraction[0];

    //convert divisor to an integer
    int denominator = fraction[2];

    //calculate how many eights
    if (numerator == '1')
    {   // 1 eighth note
        if (denominator == '8')
        {
            return 1;
        }
        // quarter note
        else if (denominator == '4')
        {
            return 2;
        }
        // half note
        else if (denominator == '2')
        {
            return 4;
        }
        // whole note
        else if (denominator == '1')
        {
            return 8;
        }
    }

    else if (numerator == '3' && denominator == '8')
    {   // 3/8ths
        return 3;
    }
    else
    {
        return 0;
    }
    return 0;
}

// Calculates frequency (in Hz) of a note
int frequency(string note)
{
    //define the letter character of string 'note'
    char letter = note[0];
    double wavelength; // returns frequency

    //determine whether the number of the octave is the 2nd or 3rd character
    int octaven;
    //check if the 2nd character is a number
    if ( (note[1] != '#') && (note[1] != 'b') )
    {
        octaven = note[1];
    }
    else
    {
        octaven = note[2];
    }

    // convert octaven from ascii value to number
    octaven -= 48;

    // Determine the distance of all notes to A4
    int n = 0; //of the frequency formula

    // double tone = 0.0; //frequency in an octave

    switch (letter)
    {
        // if (letter == 'A')
        case 'A':
        {
            n = 0;

        }
        break;

        case 'B':
        {
            n = 2;
        }
        break;

        case 'C':
            if (letter == 'C')
            {
                n = -9;
            }
            break;

         case 'D':
        {
            n = -7;
        }
        break;

        case 'E':
        {
            n = -5;
        }
        break;

        case 'F':
        {
            n = -4;
        }
        break;

        case 'G':
        {
            n = -2;
        }
        break;

        default:
            printf("Support for this note will be added soon.");
            break;
    }

    //check for sharps or flats
    if (note[1] == '#')
    {
        n += 1;
    }
    else if (note[1] == 'b')
    {
        n-=1;
    }

    //test adjustment for accidentals
    printf("%i\n", n);

    //for any octaves other than 4
    int tones;  //store the difference between 4 and octave in question
    if (octaven != 4)
    {
    //     //get the difference between octave 4 and that octave
    // you are making that adjustment, and returning before you use it to calculate the frequency.
        tones = octaven - 4;

    //     //add or subtract the difference to n (subtract if it's a negative no)
        n += tones * 12;
        // return n;
        double power = n / 12.00;
        printf("%f\n", power);
        // frequency = pow(2, n/12.0)*440 //Brenda
        wavelength = pow(2, power) * 440;
        return wavelength;
    }
    else
    {
        //test adjustment for tones
        // printf("%f\n", tones);

        // frequency = 2 ** (n / 12) * 440 // freq formula
        // find the exponent value
        double power = n / 12.00;
        printf("%f\n", power);
        // frequency = pow(2, n/12.0)*440 //Brenda
        wavelength = pow(2, power) * 440;
        return wavelength;
    }
}

// Determines whether a string represents a rest
int beats;
bool is_rest(string s)
{
    // check is user entered a blank line
    if (strncmp(s, "", 1))
    {
        return false;
    }
    else
    {
        return true;
    }
}
0

It would have been great if you had told us that your reported frequencies are only slightly off, by 1 at most.

There's no need to treat octave 4 differently (DRY).

But you might want to round the frequency, otherwise you are slightly off.

Also, returning a duration of 0 is a bold move. The synthesizer doesn't like that. Why not compute? You can turn a digit into its associated value by subtracting '0' or 48 (as you do for the frequency). Just do the multiplication by eight before you divide.

And please don't use "wavelength". Wavelength is the phase velocity (here speed of sound) divided by frequency.

2
  • BlaueIf, thanks for looking. But these are more than just slightly off, and they're not passing check50. C4 should be 523. I get 261. I changed wavelength to freq. Yes, thanks, I did see the word wavelength shadowed as a warning. I had round before, so I put it back. I also took off the extra code for octave 4. I also had it that before, btw, have just been experimenting trying to get this working. My frequency formula is still not working. :( That's frequency =(2 to the power of n/12) * 440. Correct? May 14 '18 at 19:09
  • I think C4 should be 261 Hz, so I don't see the problem. And be careful with n/12, make sure to do float division like in the posted code n/12.0.
    – Blauelf
    May 15 '18 at 6:57
0

Hallelujah, I got it to work! I believe my case syntax was wrong. I removed the curly braces after each 'case.' I'm not sure if this helped, but I also changed the case default to return 0. No disrespect to BlaueIf, of course, he is correct I should have computed the fractions as I did in an earlier version, and thank you BlaueIf for reminding me I needed to round and keep it DRY. Also to share my research I did have to use the variable power as the exponent. I learned the pow() function doesn't accept n/12 as an exponent.

You must log in to answer this question.

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