Я написал небольшой программный синтезатор для iPhone.
Для дальнейшей настройки производительности я измерил свое приложение с Shark и обнаружил, что теряю много времени в конверсиях float/SInt16.
Итак, я переписал некоторые части, чтобы обойти преобразования, предварительно вычислив таблицы поиска, которые возвращают «готовые к использованию» образцы SInt16. Пока это прекрасно.
В настоящее время я пытаюсь переписать некоторые фильтры и реализацию конверта ADSR для использования только целочисленной арифметики, но я мог бы использовать некоторые подсказки, как выполнять умножения/деления без поплавков.
Я ориентируюсь в iPhone canonical format:Избегание арифметики с плавающей точкой
- LPCM
- 16-разрядного целого число выборок
Каких хорошие подходы применять амплитуду к моей последней выборке без использования поплавка?
Edit:
Единственное, что я понял, до сих пор есть, что я могу разделить на степени 2 по сдвига вправо мой текущий образец.
inBuffer[frame] = wavetable[i % cycleLengthInSamples] >> 4;
Но я не могу придумать какой-либо элегантный способ создания гладкого конверта ADSR с этим.
Редактировать2: Спасибо за все ваши замечательные ответы!
Моего текущий подхода:
- принести всю мою ADSR конверта значения в положительный диапазон SInt16
- многократно с текущим значением из табличных (магазина промежуточных как SInt32)
- сдвига результата от 16 до право
это похоже на работу :)
Вот что я думал. Но разве вы не размножаетесь силой в два, чтобы получить свою фиксированную точку? Это касается только смещения бит. –
Сдвиг может напугать, когда вы используете подписанные ints. Силы двух более эффективны, но сложнее отлаживать. Если в первый раз использовать фиксированную точку, я бы рекомендовал десять. – patros
Спасибо за ваши ответы! Я до сих пор не нашел изящного способа реализовать конверт ADSR без поплавка. Я просто попытался сдвинуть с правой стороны образцы, что приводит к делению на произвольную мощность в два и, следовательно, уменьшает мою амплитуду - но я не могу понять, как создать с ним гладкий конверт. –