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

StackOverflow https://stackoverflow.com/questions/2373094

Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top