CS50 Pset3 музыка окончательный расчет - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь понять, почему мои последние расчеты для частотной части этого набора не рассчитываются должным образом.Я иду через отладчик, и он показывает, что «шаги» рассчитывает правильно, но расчет не работает.

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

int main(void)
{
   string note = get_string("note:");
   {
      if (strlen(note) == 2)
      {
         int key = note[0];
         int octave = atoi(&note[1]);
         int steps = 0;

         if(key == 'A')
            {
               steps = (key - 65) + ((octave - 4) * 12);
            }

         float frequencyf = (440 * (pow(2, (steps / 12))));
         int frequency = (round(frequencyf));
         printf("%i", frequency);
      }

      else if (strlen(note) == 3)
      {
         int key = note[0];
         int accidental = note[1];
         int octave = atoi(&note[2]);
         int steps = 0;

         if(accidental == '#')
           {
               if(key == 'A')
               {
                  steps = ((key - 65) + ((octave - 4) * 12) + 1);
               }
            }
        else if(accidental == 'b')
            {
               if(key == 'A')
               {
                  steps = ((key - 65) + ((octave - 4) * 12) - 1);
               }
            }

         float frequencyf = (440 * (pow(2, (steps / 12))));
         int frequency = (round(frequencyf));
         printf("%i", frequency);
      }
   }
}

1 Ответ

0 голосов
/ 27 сентября 2018

В задаче стандартная высота А4 составляет 440 Гц.Поскольку мы начинаем с клавиши А4, мы создаем массив полутонов и находим значение тона из ASCII:

A  B  C  D  E  F  G
0  2 -9 -7 -5 -4 -2

int semitones[] = {0, 2, -9, -7, -5, -4, -2};
float tone = semitones[note[0] - 'A'];

Случайные # или b поднимают или опускают ноту на один полутон.Но мы не уверены, где октава находится в примечании, и мы также должны найти ее отличие от 4-й октавы.Существуют разные сценарии, поэтому оператор switch работает хорошо:

int octave;
switch(note[1])
{
    case '#':
        tone++;
        octave = note[2];
        break;
    case 'b':
        tone--;
        octave = note[2];
        break;
    default:
        octave = note[1];
        break;
}
octave -= '4';

Частота октавы имеет коэффициент 2. A3 будет 220 Гц, а A5 - 880 Гц.Итак,

if (octave > 0)
    hz *= octave * 2;
else if (octave < 0)
    hz /= abs(octave * 2);

Наконец, частота ноты составляет 2 ^ (n / 12), где n - количество полутонов из A4:

if (tone < 0)
{
    tone *= -1;
    hz /= pow(2, tone / 12);
}
else if (tone > 0)
    hz *= pow(2, tone / 12);
...