Direct Sound в объятиях программиста Фленов Михаил Спецвыпуск Xakep, номер #044, стр. 044-014-3 Следующим этапом вызывается функция SetCooperativeLevel, которая устанавливает приоритет обработки нашего интерфейса. Не будем скромничать и используем приоритетный уровень - DSSCL_PRIORITY. Если жадность превышает все пределы, то можно повысить приоритет до максимального - DSSCL_WRITEPRIMARY. Разумеется, для особо тихих и скромных существует DSSCL_NORMAL. После этого создаем буфер для хранения звуковых данных функцией CreateSoundBuffer. В программе должен быть как минимум один первичный буфер - запросим именно его. Для этого понадобится структура типа TDSBufferDesc (в нашем случае это будет переменная dsbd), которую мы заполним нулями, чтобы в ней не оказалось какого-нибудь мусора. Нужно правильно указать два свойства: - dwSize, размер структуры; - dwFlags, флаги. В качестве флага мы указываем DSBCAPS_PRIMARYBUFFER, что соответствует первичному буферу. Теперь эту структуру необходимо указать в качестве первого параметра функции CreateSoundBuffer, а через второй параметр мы получим указатель на интерфейс буфера. Через этот интерфейс можно будет начинать и завершать воспроизведение. В отличие от классической mmsystem, в Direct Sound буфер циклический, и при достижении конца чтение или запись будет происходить с самого начала. Раньше приходилось выделять два буфера, последовательно заполнять их данными и переключать воспроизведение/запись между ними. Теперь этого делать не надо, хотя вторичные буферы всегда могут пригодиться для других целей. Если представить себе буфер данных в виде круга (см. рисунок «Буфер обмена»), то точка воспроизведения как бы движется по часовой стрелке. В этот момент мы можем без проблем пополнять буфер данными в точку записи. Прямая работа с первичным буфером очень важна, поскольку он поддерживает больше всего фильтров и эффектов. Правда, при большой нагрузке звук может выводиться с задержкой. Из этой ситуации есть выход – использовать вторичные буферы и потом микшировать их в один первичный. Интерфейс буфера должен знать, какие данные нужно воспроизводить, поэтому нужно указать формат с помощью функции SetFormat. В данном случае будет проигрываться WAV-файл, и в эту функцию придется передать структуру типа TWaveFormatEx с правильно заполненными значениями формата. Если ты кодил под MMSystem или читал мою книгу «Библия Delphi», то структура будет уже знакомой и не вызовет проблем. В принципе, все это не обязательно, и можно удалить заполнение структуры и вызов метода SetFormat, но в доках я прочитал, что так будет лучше. В реальности, даже если указать в этой структуре мусор, программа не выдаст ошибки при установке неправильного формата. Играй, невеселая песня моя Скромный интерфейс нашего примера будет содержать всего два элемента - поле ввода для указания имени файла и кнопку для воспроизведения. По нажатию кнопки нужно написать следующий код: |