Как избежать трескучих трескучих звуков после увеличения громкости в Гобой?
Я начал реализовывать библиотеку Oboe C++ для Android. (Согласно " Построить музыкальную игру с использованием гобоя" я просто масштабирую семпл для увеличения громкости, и он работает, но с потрескивающим щелчком. Могу ли я увеличить амплитуду без потрескивания? Я пытался сохранить сэмплы с небольшим усилением, но это звучит очень плохо. Спасибо.
Кстати, без увеличения громкости, это звучит ясно, но очень низкая громкость по сравнению с другими музыкальными приложениями.
for (int i = 0; i < mNextFreeTrackIndex; ++i) {
mTracks[i]->renderAudio(mixingBuffer, numFrames);
for (int j = 0; j < numFrames * kChannelCount; ++j) {
audioData[j] += (mixingBuffer[j] * ((float)volume));
}
Отредактировано:
int16_t Mixer::hardLimiter(int16_t sample) {
int16_t audioData = sample * volume;
if(audioData >= INT16_MAX){
return INT16_MAX;
}else if(audioData <= INT16_MIN){
return INT16_MIN;
}
return audioData;
};
1 ответ
Код, который вы опубликовали, взят из Mixer::renderAudio(int16_t *audioData, int32_t numFrames)
, Его задача - объединить значения семплов из отдельных треков в один массив 16-битных семплов.
Если вы микшируете 2 или более треков вместе, не уменьшая сначала значения, вы можете превысить максимальное значение семпла 32 767 (иначе INT16_MAX
). Это может привести к обтеканию (то есть запись 32 768 в int16_t
приведет к сохранению значения -32 768) и, следовательно, слышимых искажений / потрескивания.
Имея это в виду, вы можете написать очень простой (жесткий) лимитер - сделать масштабирование объема с помощью int32_t
и только записать это в int16_t
массив, если значение не превышает максимум, в противном случае просто запишите максимум.
Это не очень хороший подход, потому что вы не должны выходить за пределы 16-битных значений. Лучше было бы сначала уменьшить значения входных сэмплов, а затем добавить ступень усиления после микшера (или на отдельных дорожках внутри микшера), чтобы довести общую амплитуду до приемлемого уровня.