У меня есть приложение, которое воспроизводит потоковые аудиоданные (например, клиент чата). Рабочий процесс состоит из трех простых шагов:
- Информация заголовка файла (частота дискретизации, количество битов на выборку и количество каналов) отправляется первой.
- Устройство аудиосигнала инициализируется на основе вышеуказанных параметров.
- Аудиоданные (pcm) отправляются и воспроизводятся на указанном выше устройстве.
Код приема данных — нативный (C-код). и он читает данные из сокета. Затем он вызывает управляемый код C#, который использует библиотеку Naudio для инициализации устройства и воспроизведения звука.
Теперь проблема в том, что я вижу некоторую задержку в воспроизведении звука. Я уже оснастил остальную часть своего кода (в частности: передачу данных в сокет и передачу их обратно в управляемый код), и это, кажется, нормально. Весь процесс передачи занимает около 600 микросекунд, но после того, как я назначаю буфер Naudio
, кажется, что он начинает воспроизводить его через некоторое время (около 200-250 миллисекунд).
Вот мой класс С#, который обрабатывает часть воспроизведения звука:
class foo
{
static IWavePlayer s_WaveOut;
static WaveFormat s_WaveOutFormat;
static BufferedWaveProvider s_WaveProvider;
static byte[] s_Samples = new byte[10000];
// called from native code to init deivce with specified sample rate and num of channels
private static void DeviceInit(int rate, int bits, int channels)
{
s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
s_WaveOutFormat = new WaveFormat(rate, bits, channels);
s_WaveProvider = new BufferedWaveProvider(s_WaveOutFormat);
s_WaveProvider.DiscardOnBufferOverflow = true;
s_WaveProvider.BufferLength = 5 * 1024 * 1024;
s_WaveOut.Init(s_WaveProvider);
s_WaveOut.Play();
}
// called from native 'C' code upon receiving audio packates
private unsafe static void PlayDataCallback(
IntPtr buff,
Int32 size)
{
Marshal.Copy(buff, s_Samples, 0, size);
s_WaveProvider.AddSamples(s_Samples, 0, size);
}
}
Кто-нибудь знает, что может быть причиной задержки, или я использую его (Naudio) каким-то неправильным образом.
Я попробовал ту же библиотеку Naudio для воспроизведения wav-файла, и, похоже, она работает идеально, проблема возникает только тогда, когда я добавляю сэмплы после инициализации устройства самостоятельно.
[обновление] Если я изменю s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
на s_WaveOut = new DirectSound();
, производительность станет намного выше. Если после этого я изменю источник Naudio, чтобы установить приоритет потока воспроизведения на Highest
(по умолчанию — «Нормальный»), производительность улучшится еще больше, но, как и ожидалось, процесс начнет потреблять много ресурсов.
Спасибо,
Викрам