Автор работы: Пользователь скрыл имя, 25 Ноября 2011 в 07:49, курсовая работа
Целью моей работы является программирование в среде Windows XP АЦП и ЦАП стандартного звукового адаптера. Обе задачи реализуются на языке Borland Delphi 7.0 Enterprise в одной программе, алгоритмы и блоки которой в дальнейшем могут быть использованы в качестве основы для написания программы цифрового осциллографа либо обмена данными между ПК и радиотехническим прибором.
Введение………………………………………………………………...2
Краткие сведения об устройстве звукового адаптера………….…3
Основные понятия и возможности звукового интерфейса………5
Потоковая модель…………………...…………………………………………....5
Звуковой буфер……………………………………………………………………5
Синхронные и асинхронные устройства……………………………………....6
Полу- и полнодуплексные звуковые устройства……………………………...6
Уведомление о завершении обработки буфера………………………………..7
Подготовка буферов……………………………………………………………..7
Способы кодирования цифрового звука……………………………………….7
Формат потока…………………………………………………………………...8
Структура потока………………………………………………………………..9
Паузы, сброс и зацикливание………………………………………………….10
Поддержка нескольких процессов…………………………………………....10
Служба переназначения устройств и форматов………………………………11
Номера звуковых устройств…………………………………………………...11
Идентификаторы (ключи) открытых устройств……………………………...12
Низкоуровневое программирование звука в Windows……………………..13
Общая схема взаимодействия программы и звуковой подсистемы……...14
Структуры, используемые в звуковом интерфейсе………………………...16
Структура WAVEFORMATEX………………………………………………..16
Структуры WAVEINCAPS и WAVEOUTCAPS………………………….….18
Структура WAVEHDR………………………………………………………...19
Заключение…………………………………………………………………...….21
При завершении обработки каждого буфера драйвер устанавливает в его заголовке флаг готовности, по которому приложение может определить, что драйвер освободил данный буфер. Однако для асинхронных устройств гораздо более эффективным способом возврата буфера является уведомление (notification), при котором драйвер либо вызывает заданную функцию приложения, либо активизирует событие (event), либо передает сообщение заданному окну или задаче (thread) приложения. При этом в параметрах функции или сообщения передается также указатель заголовка буфера.
Перед тем, как быть переданным драйверу устройства, каждый звуковой буфер должен быть подготовлен (prepared). Как правило, подготовка заключается в фиксации буфера в памяти, так как большинство звуковых адаптеров пользуется внепроцессорными методами передачи данных, а эти методы требуют размещения буфера на одних и тех же адресах памяти. Передача драйверу неподготовленного буфера приводит к ошибке.
При работе со звуковыми адаптерами чаще всего используется традиционный способ цифрового кодирования PCM (Pulse Code Modulation - импульсно-кодовая модуляция, ИКМ). Ряд мгновенных значений звуковой амплитуды, следующих друг за другом с частотой дискретизации, представляется рядом чисел выбранной разрядности, значения которых пропорциональны величине амплитуды. Именно в таком виде звуковой поток снимается с выхода АЦП или подается на вход ЦАП.
Однако наряду с предельной простотой PCM обладает существенной избыточностью, передавая звук настолько точно, насколько это возможно при выбранных параметрах оцифровки. Зачастую на первый план выходит задача минимизации скорости и объема звукового потока, в то время как отдельными параметрами точности и качества можно пренебречь. В таких случаях используются другие способы кодирования, когда звуковая информация представляется в виде относительных изменений амплитуды (ADPCM – adaptive differential PCM, адаптивная разностная ИКМ), мгновенных “снимков” спектра (Audio MPEG) и т.п.
Обрабатывать звук в PCM способен любой звуковой адаптер. Иные способы кодирования аппаратно реализуются лишь в специализированных адаптерах.
Совокупность основных параметров потока - способа кодирования, частоты дискретизации, количества каналов (стерео/моно) и разрядности отсчета - называется форматом потока (Wave Format). Желаемый формат указывается при открытии устройства; для смены формата требуется закрытие и повторное открытие устройства.
Главным параметром формата является способ кодирования, который также называется еще признаком формата (format tag). Каждый способ кодирования порождает группу однотипных форматов, различающихся лишь точностью представления, а следовательно, и качеством передачи звука.
Основные частоты дискретизации (11025, 22050 и 44100 Гц) в сочетаниях с различным количеством каналов (1 или 2) и различной разрядностью отсчета (8 или 16) при способе кодирования PCM образуют 12 типовых форматов. Частота 11025 Гц (полоса звуковых частот примерно до 5 кГц) приблизительно соответствует качеству телефонного сигнала, частота 22050 Гц (полоса до 10 кГц) - среднего радиоприемника, частота 44100 Гц (полоса до 20 кГц) - качественной звуковой аппаратуре.
Наименьшей единицей звукового потока является блок. Соответственно, размер каждого буфера, передаваемого звуковой подсистеме, должен быть кратен размеру блока, а объем данных, возвращаемый устройством ввода, всегда будет кратен размеру блока.
В PCM блоком считается набор отсчетов, передаваемых за один период частоты дискретизации, а именно: один отсчет - для монофонических потоков, два - для стереофонических, и т. д. Таким образом, блоки следуют друг за другом с частотой дискретизации, а отсчеты в блоках размещаются, начиная с левого (нулевого) канала.
Восьмиразрядные отсчеты в PCM представляются в виде беззнаковых целых чисел; за нуль сигнала принято “центральное” значение 128 (шестнадцатеричное — 80). Итак, предельной отрицательно амплитуде сигнала соответствует нулевое значение отсчета, а предельной положительной - значение FF. Для пересчета значений отсчетов в знаковую двуполярную форму в диапазоне от -128 до +127 из них нужно вычитать 128 (0x80), или прибавлять то же самое смещение, вычисляя по модулю 256, что дает такой же результат.
Отсчеты с разрядностью более восьми представляются в виде целых чисел со знаком в стандартном формате Intel: за нуль сигнала принято нулевое значение отсчета. Здесь может без каких-либо ограничений применяться обычная целая арифметика, например над типами short (16-разрядный) и long (32-разрядный).
Если разрядность отсчета превышает 16, она может быть не кратна байту - современные звуковые адаптеры могут использовать 18-, 20- и 22-разрядные отсчеты. В таком случае отсчет выравнивается по старшей границе трех- или четырехбайтового слова, а лишние младшие разряды заполняются нулями. Подобное представление позволяет работать с отсчетами любой разрядности так же, как с 24- или 32-разрядными; от фактической разрядности отсчета зависит лишь точность полученного числа.
24-разрядные трехбайтовые слова - достаточно неудобная для современного компьютера единица данных, поэтому в целях оптимизации некоторые адаптеры и драйверы могут использовать четырехбайтовые 32-разрядные слова для отсчетов с разрядностью более 16. В любом случае фактическая разрядность отсчета задается параметром разрядности формата, а размер слова, в котором размещается отсчет, определяется из размера блока, путем деления его на количество каналов в потоке.
В форматах других типов размер и структура блока подчиняются собственным правилам; зачастую блок сводится к одному байту.
Циклическое движение буферов может быть приостановлено и затем возобновлено с места прерывания с сохранением позиции в потоке. Поток может быть уничтожен (сброшен) - в этом случае драйвер немедленно возвращает приложению все ждущие буферы и обнуляет позицию потока.
Для устройств воспроизведения один или несколько идущих подряд буферов могут быть зациклены (looped): в этом случае драйвер последовательно проигрывает их заданное количество раз, после чего возвращает приложению и переходит к воспроизведению следующих буферов из очереди.
Звуковая подсистема Windows допускает работу с устройством нескольких процессов (клиентов) одновременно. Многие современные и даже некоторые устаревшие звуковые устройства поддерживают более одного клиента; устройство вывода (или его драйвер) смешивает проигрываемые клиентами звуковые потоки, а устройство ввода размножает записываемый поток для всех подключенных клиентов.
Устройство, драйвер которого поддерживает не более одного клиента, не может быть повторно открыто до тех пор, пока клиент не закроет его. При попытке повторно открыть такое устройство звуковая подсистема возвращает сообщение об ошибке, сигнализирующее о том, что устройство занято.
Для упрощения реализации основных операций со звуком Windows содержит службу переназначения - Wave Mapper. Поскольку в Windows может быть установлено более одного звукового устройства, существуют понятия стандартного системного устройства ввода и стандартного системного устройства вывода. Оба они задаются в закладке Audio формы свойств мультимедиа. Приложение может запросить работу с конкретным звуковым устройством либо со стандартным системным - в последнем случае служба переназначения определяет нужное устройство.
Кроме трансляции запросов к нужному устройству, Wave Mapper может выполнять и поиск наиболее подходящего устройства, поддерживающего требуемый формат звука.
Звуковая подсистема нумерует установленные устройства начиная с нуля. При установке нового устройства или удалении существующего нумерация изменяется, поэтому даже во время работы программы в системе могут появиться или исчезнуть звуковые устройства.
Вместо номера звукового устройства может использоваться ключ (handle) ранее открытого устройства; система автоматически определяет, какое именно значение передано интерфейсной функции.
Как и в случае с файлами, при открытии каждого звукового устройства система возвращает его идентификатор, или ключ (handle), по которому затем происходит вся остальная работа с устройством. Формально идентификаторы устройств ввода и вывода имеют различные типы — HWAVEIN и HWAVEOUT, однако оба они эквивалентны типу HWAVE, который может использоваться для создания универсальных функций, не зависящих от типа устройства.
Ключи звуковых устройств не имеют ничего общего с ключами файлов, событий, окон, задач и т.п. Системные функции DuplicateHandle, CloseHandle и прочие к ним не применимы.
Если программе безразлично, с каким конкретным устройством она будет работать, либо если работа ведется только со стандартным системным устройством, то программа может ориентироваться только на службу переназначения. В противном случае программа определяет количество имеющихся в системе устройств ввода и/или вывода при помощи функций GetNumDevs.
При
необходимости программа может
запросить параметры и имена
звуковых устройств при помощи функций
GetDevCaps, чтобы, например, сформировать меню
доступных устройств для
Работа
программы с устройством
Затем программа создает (обычно в динамической памяти) один или несколько звуковых буферов с заголовками и заполняет заголовки в соответствии с установленными правилами. Программа может также сразу подготовить все звуковые буферы к передаче драйверу функциями Prepare либо сделать это непосредственно перед передачей каждого очередного буфера.
Цикл записи начинается с накопления в очереди драйвера нескольких буферов при помощи функции AddBuffer. После накопления нужного количества буферов программа запускает запись потока функцией Start. В этот момент драйвер запускает АЦП адаптера, и звуковые отсчеты начинают поступать в первый буфер из очереди.