AIMP Forum
Общее => Общение / General => Topic started by: Aleksoid1978 on May 28, 2013, 06:52:38
-
Привет всей команде AIMP, вы молодцы, говорю не только как пользователь, а как и разработчик.
Я разработчик MPC-BE, и в данный момент дернул черт меня заняться Audio выводом, через WASAPI. Есть проблемы в Exclusive режиме, причем на моих 3-х машинах все хорошо, а пользователи жалуются - в этом режиме присутствует шум, трески и т.д.
Если будет желание "помочь" - буду очень признателен, даже если советом.
-
Приветствую.
В каком формате у вас идут данные на интерфейс? Перед тем как помещать их в буфер вы проверяете их на "out of bouds" (актуально, если приходится преобразовывать из одного формата сэмплов в другой)? Какой из механизмов заполнения буфера WASAPI интерфейса вы используете, Push или Event? Трекс может наблюдаться как из-за "пробелов" в самих аудиоданных, так и из-за того, что программа во время не успела наполнить буфер интерфейса (это актуально для эксклюзив режима, т.к. латенси у него очень маленькая)
-
Данные, приходящие от нижестоящего фильтра, в моем случае от Аудио-декодера, в случае Exclusive, перерабатываются Микшером, т.к. преобразуются в нужный формат.
Использую EVENT. Примерно происходит так - в одной функции(стандартной) получаются данные из IMediaSample. Обрабатываются, если это надо, и складываются в буфер. В отдельном потоке, причем я ему выставил приоритет высокий, по событию берутся данные
m_pRenderClient->GetBuffer(numFramesAvailable, &pData);
копирую в pData из своего буфера и все.
В отладчике смотрю, данных хватает, т.к. мой буфер всегда заполнен, не происходит его опустошение. Но видимо, по какой-то причине, сам механизм не успевает чтоли пережевывать данные или что-то в этом роде.
Что можеш посоветовать. Самое что интересное - что на одних системах все ок, на других наблюдаются периодические щелчки, искажения и т.д.
-
Данные, приходящие от нижестоящего фильтра, в моем случае от Аудио-декодера, в случае Exclusive, перерабатываются Микшером, т.к. преобразуются в нужный формат.
Использую EVENT. Примерно происходит так - в одной функции(стандартной) получаются данные из IMediaSample. Обрабатываются, если это надо, и складываются в буфер. В отдельном потоке, причем я ему выставил приоритет высокий, по событию берутся данные
m_pRenderClient->GetBuffer(numFramesAvailable, &pData);
копирую в pData из своего буфера и все.
В отладчике смотрю, данных хватает, т.к. мой буфер всегда заполнен, не происходит его опустошение. Но видимо, по какой-то причине, сам механизм не успевает чтоли пережевывать данные или что-то в этом роде.
Что можеш посоветовать. Самое что интересное - что на одних системах все ок, на других наблюдаются периодические щелчки, искажения и т.д.
Дамп буфера делали? Резких скачков / падений нигде нет?
-
Дамп буфера делали? Резких скачков / падений нигде нет?
С буфером данных все ок.
Сразу задам еще один вопрос. Уже касается момента инициализации. По спекам от MS, делаем так
GetDevicePeriod(NULL, &hnsPeriod);
далее вызываем Initialize() и проверяем код возврата
if (AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED == hr) ...
мы пересчитываем размер, чтобы получить выравненный буфер. Так вот я столкнулся с такой ситуацией, что Initialize() возвращает S_OK, но размер буфера не выровненный, и далее у нас посторонние шумы и помехи во время проигрывания. Опытным путем я выяснил что размер должен быть кратен 128, и мне пришлось еще дополнительно вручную проверять это, и если, исправлять(увеличивать размер). После этого проигрывание идет нормально. Причем, что самое интересное, такое происходит на некоторых системах, в то же время на других все правильно, размер буфера нужный и т.д.
С таким не сталкивались ??
-
мы пересчитываем размер, чтобы получить выравненный буфер. Так вот я столкнулся с такой ситуацией, что Initialize() возвращает S_OK, но размер буфера не выровненный, и далее у нас посторонние шумы и помехи во время проигрывания. Опытным путем я выяснил что размер должен быть кратен 128, и мне пришлось еще дополнительно вручную проверять это, и если, исправлять(увеличивать размер). После этого проигрывание идет нормально. Причем, что самое интересное, такое происходит на некоторых системах, в то же время на других все правильно, размер буфера нужный и т.д.
На сколько у вас при этом большой размер буфера?
ASize := Max(AMinPeriod, SecondsToRefTime(SOUNDOUT_DEVICE_BUFFER_DURATION));
AError := Client.Initialize(acsmExclusive, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, ASize, ASize, @AFormat, nil);
if AError = AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED then
...
Единственное, что я делаю - ограничиваю минимальный размер буфера 0.1 секундой
-
На сколько у вас при этом большой размер буфера?
ASize := Max(AMinPeriod, SecondsToRefTime(SOUNDOUT_DEVICE_BUFFER_DURATION));
AError := Client.Initialize(acsmExclusive, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, ASize, ASize, @AFormat, nil);
if AError = AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED then
...
Единственное, что я делаю - ограничиваю минимальный размер буфера 0.1 секундой
Ок - спасибо, проверю что у меня получается, какой размер.
-
Спасибо за подсказку. Да - проблемы были из-за очень маленького размера буфера. Я брал(как по доке) минимальный размер буфера, которое поддерживается устройством. У меня к примеру оно равно было 3 мс, после выравнивания становилось примерно 3.8 мс, получается что ~260 раз в секунду надо было данные заполнять. Сделал 0.1 сек, и действительно стало лучше.
Еще один вопрос - вы время паузы, перемотки "паузите" рабочий поток или дальше обрабатываете Event , но только с флагом AUDCLNT_BUFFERFLAGS_SILENT ??
-
Еще один вопрос - вы время паузы, перемотки "паузите" рабочий поток или дальше обрабатываете Event , но только с флагом AUDCLNT_BUFFERFLAGS_SILENT ??
При паузе в интерфейс идут нулевые данные, такой подход решил использовать потому, что не во всех интерфейсах есть возможность ставить устройство на паузу.
-
При паузе в интерфейс идут нулевые данные, такой подход решил использовать потому, что не во всех интерфейсах есть возможность ставить устройство на паузу.
Спасибо, я именно так и сделал. Не стал останавливать IAudioClient, а просто шлю "тишину".