Загрузка больших мультисэмпловых аудиофайлов в память для воспроизведения - как избежать временного зависания - PullRequest
3 голосов
/ 03 марта 2010

Я пишу, что приложение должно использовать большие звуковые мультисэмплы, обычно размером около 50 МБ. Один файл содержит около 80 отдельных коротких звуковых записей, которые могут быть воспроизведены моим приложением в любое время. По этой причине все аудиоданные загружаются в память для быстрого доступа.

Однако при загрузке одного из этих файлов может потребоваться много секунд, чтобы поместить в память, то есть мою программу, если она временно заморожена. Каков хороший способ избежать этого? Он должен быть совместим с Windows и OS X. Он замерзает при этом: myMultiSampleClass->open();, что требует большого динамического выделения памяти и чтения из файла с использованием ifstream.

Я подумал о двух возможных вариантах:

  1. Откройте файл и загрузите его в память в другом потоке, чтобы процесс моего приложения не зависал. Я заглянул в библиотеку Boost, чтобы сделать это, но мне нужно много читать, прежде чем я буду готов к реализации. Все, что мне нужно сделать, это вызвать функцию open () в потоке, а затем уничтожить поток.

  2. Придумайте схему, чтобы убедиться, что я не загружаю весь файл в память одновременно, я просто загружаюсь на лету, так сказать. Проблема в том, что любой образец может быть запущен в любое время. Я знаю, что какое-то другое программное обеспечение имеет такую ​​систему, но я не уверен, как она работает. Это во многом зависит от спецификаций отдельных компьютеров, это может отлично работать на моем компьютере, но кто-то с медленным жестким диском / памятью может получить очень плохие результаты. У меня была идея загрузить x сэмплов каждой аудиозаписи в память, а затем, если мне нужно воспроизвести, начать воспроизведение уже существующих сэмплов, одновременно загружая оставшуюся аудиозапись в память.

Есть идеи или критические замечания? Заранее спасибо: -)

Ответы [ 4 ]

1 голос
/ 03 марта 2010

Использовать отображенный в памяти файл .Время загрузки изначально «мгновенное», и накладные расходы ввода-вывода будут распределяться по времени

0 голосов
/ 04 марта 2010

Я думаю, что лучшим решением является загрузка небольшого фрагмента или одной выборки волновых данных за один раз во время воспроизведения с использованием асинхронного ввода-вывода (как упоминал Джон Диблинг) в фиксированный размер буфера воспроизведения.

стратегия будет сначала заполнять буфер воспроизведения, а затем воспроизводить (это добавит небольшую задержку, но гарантирует непрерывное воспроизведение), во время воспроизведения буфера вы можете повторно заполнить другой буфер воспроизведения в другом потоке (перекрывающемся), по крайней мере вам нужно иметь два буфера воспроизведения, один для воспроизведения и один для пополнения в фоновом режиме, а затем переключать его в режиме реального времени

позже вы можете установить, насколько велик размер буфера воспроизведения на основе производительности клиентского ПК (это будет компромисс между объемом памяти и вычислительной мощностью, для самого быстрого процессора потребуется меньший буфер, а значит, и меньшая задержка).

0 голосов
/ 03 марта 2010

Мне нравится решение 1 в качестве первой попытки - просто и точно.

Если вы находитесь под Windows, вы можете выполнять асинхронные файловые операции - что они называют OVERLAPPED - чтобы указать ОС загрузить файл и сообщить, когда он будет готов.

0 голосов
/ 03 марта 2010

Возможно, вы захотите рассмотреть подход производитель-потребитель . В основном это включало чтение звуковых данных в буфер с использованием одного потока и потоковую передачу данных из буфера на звуковую карту с использованием другого потока.

Считыватель данных является производителем, а потоковая передача данных на звуковую карту - потребителем. Вам нужны метки верхнего и нижнего уровня, чтобы при переполнении буфера производитель прекратил чтение, а при низком уровне буфера производитель снова начал читать.

Библиотека шаблонов параллелизма производителя и потребителя C ++
http://www.bayimage.com/code/pcpaper.html

РЕДАКТИРОВАТЬ: Я должен добавить, что такого рода вещи сложно. Если вы создаете проигрыватель сэмплов, нагрузка на систему постоянно меняется в зависимости от того, какие клавиши воспроизводятся, сколько звуков воспроизводится одновременно, какова продолжительность каждого звука, нажата ли педаль сустейна, и другие факторы, такие как скорость жесткого диска и буферизация, а также объем доступной мощности процессора. Некоторые оптимизации программирования, которые вы в конечном итоге используете, не будут очевидны на первый взгляд.

...