#audio #audio-streaming #mixing #mixer #conference
#Аудио #потоковое аудио #смешивание #миксер #конференция
Вопрос:
Для аудиоконференции у меня есть аудиоданные (короткий массив аудио-сэмплов, 16-битный звук 16 кГц) для каждого участника, и я хочу смешать их в один короткий массив, чтобы я мог воспроизвести его на стороне клиента. Смешивание находится на стороне клиента для архитектуры SFU.
Я искал и нашел много ответов, многие из которых были получены давным-давно, например, для 2 образцов A и B, выполняя A B-A*B (что имеет недопустимые искажения) и суммируя все образцы, а затем деля их на количество участников (что может привести к заметному снижению громкости участника?), динамический контроль усиления после суммирования образцов и отслеживания наклона, чтобы держать его под контролем. Основная проблема заключается в ограничениях в реальном времени. Я попробовал что-то вроде этого :
public synchronized int mix(ArrayListlt;AudioFrameShortgt; rawData, short [] output, int outOffset){ if(rawData.size() == 0) return 0; else if(rawData.size() == 1){ System.out.println("size 1"); AudioFrameShort shortFrame = rawData.get(0); System.arraycopy(shortFrame.data, 0, output, outOffset, shortFrame.len); return shortFrame.len; } int dataLength = rawData.get(0).len; for(int i=1; ilt;rawData.size(); i ) if(rawData.get(i).len lt; dataLength) dataLength = rawData.get(i).len; for (int j = 0; j lt; dataLength; j ){ double mixed = 0; for (int k = 0; k lt; rawData.size(); k ){ double gain = 1;//rawData.get(k).gainControl.getCurrentGain(); mixed = (gain * rawData.get(k).data[j] / 32768.0f); } if (mixed gt; 1.0f){ mixed = 1.0f; } if (mixed lt; -1.0f) { mixed = -1.0f; } output[outOffset j] = (short)(mixed * 32768.0f) } return dataLength;}
мой вопрос в том, какой на сегодняшний день лучший способ и какой алгоритм используют лидеры отрасли, такие как skype, zoom, discord, для микширования звука на стороне клиента, предотвращая переполнение и сохраняя плавность даже для большой конференции. Заранее спасибо.