Создание прямоугольной, пилообразной и треугольной волны в Objective-C

Я пытаюсь сгенерировать различные формы волн для простого приложения iOS для синтеза волн, над которым я работаю. Вот как я генерирую синусоиду:

        if (waveType == 1) // sine wave
    {
        //NSLog(@"sine in AU");
        for (int i=0;i<n;i++)
        {
            float x = 0.0;        // default to silence
            if (toneCount > 0)  // or create a sinewave
            {
                x = testVolume * sinf(ph);
                ph = ph + dp;

                if (ph > M_PI) { ph -= 2.0 * M_PI; } // sine wave

                toneCount -= 1;    // decrement tone length counter
            }
            if (ptrLeft  != NULL){
                ptrLeft[ i] = x;
            }
            if (ptrRight != NULL) {
                ptrRight[i] = x;
            }
        }
    }

Для прямоугольной волны я предполагал, что это сработает, но это не так:

if (ph > M_PI) { 
ph -= 2.0 * M_PI;
ph >= 0 ? 1.0 : -1.0;
}

Как мне создать пилообразные и треугольные волны и где прямоугольная волна идет не так?

Спасибо, я новичок в программировании для iOS и люблю работать со звуком.


person studenttttt    schedule 10.04.2018    source источник


Ответы (1)


Для начала подумайте о своей линии

if (ph > M_PI) { ph -= 2.0 * M_PI; } // sine wave

ph - это ваш вход в вашу функцию sin, которая представляет собой некоторое значение в радианах ... имейте в виду, что функция sin автоматически обрабатывает значения, превышающие 2 * PI, она просто обертывает ее, поэтому вам не нужно управлять вашей переменной ph, кроме как просто увеличивать ее.

Что касается вашей прямоугольной волны ... имейте в виду, что ваш выход имеет только два значения: низкое или высокое ... не управляйте переключением между низким / высоким значением кривой.

if (ph > M_PI) { 
    ph -= 2.0 * M_PI;
    ph >= 0 ? 1.0 : -1.0;
}

имейте в виду, что по мере того, как вы увеличиваете свой внешний цикл i, вы увеличиваете ph, который вы используете, чтобы определить, где вы находитесь в своих циклах PI, что в порядке, однако тот же самый ph затем также не может быть введен в sin (ph) ... что-то еще должно быть загружено в sin(), иначе что-то еще поддерживает вашу позицию выборки в вашем цикле PI ... вы ошибочно объединяете две обязанности в одну переменную

В приведенном выше блоке кода подумайте, когда вы должны выполнить переключение с низкого уровня на высокий или обратно с высокого на низкий ... это происходит в M_PI? сколько таких переключений происходит за цикл? когда ? возможно, вам нужен дополнительный тест if, чтобы определить, когда выполнять это переключение ... в вашем алгоритме кривой синусоиды вы уже управляете ph, должны ли вы обрабатывать ph прямоугольной волны по-другому или оставить логику ph такой же?

person Scott Stensland    schedule 12.04.2018
comment
Спасибо за совет! В конце концов я понял, что, как вы сказали, я перестал использовать ph, и мне нужно было оставить его, чтобы определить, на каком этапе цикла PI я нахожусь. Поэтому вместо этого я использовал x для создания сигналов. Дополнительный вопрос: когда я запускаю два осциллятора, один из которых представляет собой синусоидальную волну, а другой — квадратную, когда я пытаюсь суммировать их, это звучит гораздо более резко, чем то, как звучит обычный синтезатор с волновой таблицей, такой как Massive. Вот с чем я работаю, если у вас есть какие-либо советы. Еще раз спасибо. - person studenttttt; 17.04.2018
comment
х = testVolume * sinf (ph); // синусоида y = testVolume * sinf(ph) ›=0 ? 1,0 : -1,0; // прямоугольная волна с плавающей запятой z = yn * ((x*0.5) + (y*0.5)); где z - выход - person studenttttt; 17.04.2018
comment
это уравнение z выглядит хорошо, за исключением того, что такое yn ? не думаю, что это необходимо, если только это не какой-то фактор растяжения - person Scott Stensland; 17.04.2018
comment
Я предлагаю вам визуализировать выходной звук... инструмент проверки под названием Audacity, который будет отображать звук в виде кривой, что важно при манипулировании звуком... он позволяет увеличивать масштаб, чтобы просмотреть все детали кривой... вы также можете написать код построить кривую - person Scott Stensland; 17.04.2018
comment
мои извинения за то, что я не включил какие-либо комментарии о yn, это разностное уравнение для БИХ-фильтра, который я использую для фильтрации сигнала! Я еще не заставил его работать должным образом, потому что я выясняю, как получить вывод сгенерированных волн в качестве входных данных для фильтра, но я обновлю, когда у меня будет! Кроме того, я начну изучать график кривой, чтобы увидеть, где именно я ошибаюсь. Еще раз спасибо. - person studenttttt; 18.04.2018