Ошибка логики опустошения буфера, учебник по многопоточности? - PullRequest
0 голосов
/ 05 августа 2010

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

У меня есть следующая проблема: Я используюAPI для доступа к аппаратному обеспечению, которое я не кодировал, для добавления библиотек к этому API, которое мне нужно наследовать от интерфейса API, и API делает все.

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

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

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

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

Или тот, который я на самом деле понял, логика: сделать музыкальную библиотеку иметь свой собственный поток, у нее будет свой отдельный буфер, который он будет заполнять все время, когда API вызывает музыкубиблиотека для дополнительных данных, вместо генерации, она просто скопирует данные из этого отдельного буфера в буфер звуковой карты, а затем возобновит генерацию музыки.

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

Вопрос в том, может ли кто-нибудь найти другое решение, ИЛИ указать мне место, которое даст мне информацию о том, как реализовать моиРезьбовое решение?

РЕДАКТИРОВАТЬ:

Я не ЧИТАЮ файлы, Я ОБУЧАЮ, или РАСЧЕТаю музыку, понял?Это НЕ библиотека .wav или .ogg.Вот почему я упомянул процессорное время: если бы я мог использовать 100% CPU, я бы никогда не получил опустошение, но я могу использовать CPU только в течение короткого времени между программой, понимающей, что буфер достигает конца, и фактическим концомбуфер, и это время иногда меньше, чем время, необходимое программе для расчета музыки.

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

Я считаю, что решение с отдельным потоком, который подготовит данные для библиотеки, чтобы она была готова по запросу, - лучший способ уменьшить задержку и решить эту проблему.Один поток генерирует музыкальные данные и сохраняет их в буфере, а поток API получает данные из этого буфера, когда это необходимо.В этом случае вам нужно синхронизировать доступ к буферу, когда вы читаете или пишете, и убедиться, что у вас нет слишком большого буфера в тех случаях, когда API слишком медленный.Чтобы реализовать это, вам нужны примитивы потока, мьютекса и условия из библиотеки потоков и два флага - один для указания, когда запрашивается останов, и другой, чтобы попросить нить приостановить заполнение буфера, если API не может идти в ногу, и он становится слишком большим.Я бы рекомендовал использовать библиотеку Boost Thread для C ++, вот несколько полезных статей с примерами, которые приходят на ум:

0 голосов
/ 06 августа 2010

Вам не обязательно нужен новый поток для решения этой проблемы.Ваша операционная система может обеспечить асинхронную операцию чтения;Например, в Windows вы должны открыть файл с помощью FILE_FLAG_OVERLAPPED, чтобы выполнить любые операции над ним асинхронно.

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

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

...