2015-02-24 3 views
1

У меня есть два аудиофайла, которые я читал при использовании libsndfile.Пытается смешивать два источника звука PCM

SNDFILE* file1 = sf_open("D:\\audio1.wav", SFM_READ, &info); 
SNDFILE* file2 = sf_open("D:\\audio2.wav", SFM_READ, &info2); 

После того как я сделал предыдущий пример я х-число образцов:

//Buffers that will hold the samples 
short* buffer1 = new short[2 * sizeof(short) * 800000]; 
short* buffer2 = new short[2 * sizeof(short) * 800000]; 

// Read the samples using libsndfile 
sf_readf_short(file1, buffer1, 800000); 
sf_readf_short(file2, buffer2, 800000); 

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

short* mixdown = new short[channels * sizeof(short) * 800000]; 
for (int t = 0; t < 800000; ++t) 
{ 
    mixdown[t] = buffer1[t] + buffer2[t] - ((buffer1[t]*buffer2[t])/65535); 
    t++; 
    mixdown[t] = buffer1[t] + buffer2[t] - ((buffer1[t]*buffer2[t])/65535); 
} 

После этого я ecoding новый аудио с помощью FFmpeg:

FILE* process2 = _popen("ffmpeg -y -f s16le -acodec pcm_s16le -ar 44100 -ac 2 -i - -f vob -ac 2 D:\\audioMixdown.wav", "wb"); 
fwrite(mixdown, 2 * sizeof(short) * 800000, 1, process2); 

Теперь проблема в том, что звук из buffer1 хорошо звучит в сведении но только «добавлено» к новому звуку - это шум (например, если это старая аудиозапись), когда я кодирую микширование в файл.

Если я кодирую только один из двух файлов, он отлично работает.

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

Я также прочитал другую информацию о SO о людях, имеющих похожие вопросы, но я не мог понять это.

Заранее спасибо

+0

Здесь вы не смотрите на стереоканалы. Надеюсь, это потому, что это упрощенный пример. – MSalters

+0

Что вы имеете в виду? Что я должен изменить? (for-loop в моем вопросе теперь один из ответа) – Dries

+0

Ну, вы не проверяете, что audio1.wav и audio2.wav имеют одинаковое количество каналов. Но разумно оставить такие проверки из упрощенного примера. – MSalters

ответ

3

Ваш код смешивания очень странно - кажется, вам следует добавить нелинейный термин, который приведет к искажению - это, кажется, хак специально для 8 битого PCM, где динамический диапазон очень ограниченный, но вам, вероятно, не нужно беспокоиться об этом для 16-битного PCM. Для основного смешивания вы просто хотите это:

for (int t = 0; t < 800000 * 2; ++t) 
{ 
    mixdown[t] = (buffer1[t] + buffer2[t])/2; 
} 

Следует отметить, что деление на 2 необходимо, чтобы предотвратить искажение, когда у вас есть два полномасштабных сигналы. Также обратите внимание, что я удалил разворот двух циклов.

+1

EDIT: nvm, которая исправила это! Большое спасибо – Dries

+0

Этот хак, вероятно, не для PCM. Я думаю, что взлом был создан кем-то, кто не знал, что он работает над данными ULaw, и, следовательно, попробовал несколько простых арифметических операций по целочисленной интерпретации значения uLaw. – MSalters

+0

@MSalters: aha - yes - μLaw будет иметь смысл. –

1

Ваш алгоритм правильный, но вы пропустили важный момент: диапазон вашего PCM составляет от -32768 до 32767. Таким образом, вы должны делить на 32768, а не 65535.