Генерирующая волна греха создает шум - PullRequest
1 голос
/ 23 марта 2019

У меня есть простая программа на C для генерации прямоугольной волны с определенной частотой, частотой дискретизации и амплитудой, которая отлично работает. Однако, если я закомментирую соответствующую строку и раскомментирую новую синусоидальную линию, она генерирует мою синусоидальную волну, но также создает много шума при обработке вывода в Audacity или SoX .

Однако, файл журнала, содержащий данные в моем сгенерированном буфере, читается, как и ожидалось, со знаковыми значениями в пределах амплитуды, колеблющимися во времени (выборки) относительно указанной частоты, без неожиданных значений или шума ...

Это может привести меня к мысли, что что-то не так с частотой дискретизации или какими-то другими настройками (порядковый номер, моно / стерео, тип данных и т. Д.), Но, как я уже говорил, у прямоугольной волны таких проблем нет. Также я гарантировал, что все вычисления были выполнены с использованием плавающего типа двойной точности, так что я знаю, что целочисленное приведение не является моей проблемой. Я в тупике. Любая помощь или понимание приветствуется.

Вот что у меня есть:

#define pi 3.1415926

int main()
{
    FILE *fer=fopen("log.txt","w");
    double f=440; //freq
    double a=1000; //amplitude
    double p=44100/f; //period

    int16_t *b=malloc(sizeof(int16_t)*44100);
    if(!b)return 1;

    for(int i=0;i<44100;i++)
    {
        double ll=sin( (2.0L*pi/p)*i ) * a;   //SINE WAVE
        // double ll=fmod(i,p)<p/2?a:-a;   //SQUARE WAVE
        b[i]= ll;
        fprintf(fer,"%i\n",b[i]);
    }

    fwrite(b,sizeof(int16_t),44100,stdout);

    free(b);
    fclose(fer);
}

1 Ответ

1 голос
/ 23 марта 2019

Вы отправили двоичный вывод на stdout, который является текстовым потоком, и вы, вероятно, перенаправили его в файл.На некоторых ОС символ новой строки в текстовом потоке конвертируется.Поэтому, когда видно значение байта 0x0A или, возможно, 0x0D, оно преобразуется в другое значение или, возможно, в два значения.Это может быть частью 16-разрядного значения, например 0x0D00, и система не знает, что это 16-разрядные значения.Одна подсказка в том, что размер результирующего файла больше ожидаемого.

Решение состоит в том, чтобы открыть файл в двоичном режиме и записать в него данные.

О другом комментарии: базовое значение,Иногда данные должны иметь свой центр (нулевое значение) в 0x8000, и данные обрабатываются как неподписанные и корректируются игроком.Я заметил, что ваши обрабатываются как подписанные данные без смещения нуля.

Это означает, что для вашей амплитуды 1000 данные находятся либо в диапазоне от -1000 до +1000, либо в диапазоне 31768 до 33768.

...