1

I'm on my final check for this pset. The last check I keep getting the wrong round direction. I need C#3 to return 139 not 138, seems like a simple enough fix but anytime I change the result and add or remove 'round' it screws with the other results. Need someone else to look at the code and provide some thought provoking insight to my issue. It's in the frequency function. I added some temporary notes in just to assist with what my thought process is at this time.

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>

#include "helpers.h"

// Converts a fraction formatted as X/Y to eighths

int duration(string fraction)
{

    // TODO

    int beat = fraction[0] -'0';
    int count = fraction[2]-'0';

    return ((16 / count) * beat/2);
}


// Calculates frequency (in Hz) of a note

int frequency(string note)

{

    char note_letter = note[0];

    char octave = note[strlen(note) - 1];

    // CHECKING IF NOTE INPUT IS BETWEEN RANGES AVAILABLE ON A KEYBOARD
    if ((note_letter < 'A' || note_letter > 'G' ) || (octave < '0' || octave > '8'))
        return 1;

    int middle_hz = 440; //STARTING POINT FOR MIDDLE A
    int full_step = (octave - '4'); //CHECKS DISTANCE OF OCTAVE WITH MID 'A'
    int hz = round(middle_hz * pow(2, full_step));
    float a = 0., b = 2., c = -9., d = -7., e = -5., f = -4., g = -2.; //STEPS BETWEEN SEMITONES ON KEYS

    int freq;
    float x;

    switch (note_letter)
    {
        case 'A':
        x = a;
        break;

        case 'B':
        x = b;
        break;

        case 'C':
        x = c;
        break;

        case 'D':
        x = d;
        break;

        case 'E':
        x = e;
        break;

        case 'F':
        x = f;
        break;

        case 'G':
        x = g;
        break;

        default:
        return 1;
    }

    int raw_hz = round(hz * pow(2, x/12));//*Until I figure it out, passes directly through to return
    int res = (hz * pow(2, x/12));//*Until I figure it out(passes to through to accidentals)

    //CHECKS IF ACCIDENTALS ARE PRESENT IF SO RAISE/LOWER 1 SEMITONE FOR '#' AND 'B'
    if (note[1] == '#')
    {
        freq = round(res * pow(2., 1./12.));
        return (freq);
    }
    else if (note[1] == 'b')
    {
        freq = round(res / pow(2., 1./12.));
        return (freq);
    }
    return (raw_hz);
}


// Determines whether a string represents a rest

bool is_rest(string s)
{

    // TODO

    if (s[0] == '\0')
    {
        return true;
    }
    return false;

}
1
  • How did you know to use these values for the steps on the semitones? I used "1, 2, 3....n" based on the # of steps from A and was calculating half of the freq correct and half either 2x or 1/2x...but when I substituted for these, it worked. {float a = 0., b = 2., c = -9., d = -7., e = -5., f = -4., g = -2.;} – Jake Jun 22 '18 at 18:59
5

Found the answer:

The variable that is passed into the Accidental condition must be a float not an int.

float res = (hz * pow(2, x / 12));

NOT: int res = (hz * pow(2, x/12));

You must log in to answer this question.

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