Запись звуковых данных
Процесс записи похож на процесс воспроизведения.
Вначале необходимо открыть устройство записи, вызвав функцию waveInOpen :
Функция waveInOpen
UINT waveInOpen( LPHWAVEIN lphWaveIn, // указатель на идентификатор устройства UINT wDeviceID, // номер открываемого устройства LPWAVEFORMAT lpFormat, // указатель на структуру WAVEFORMAT DWORD dwCallback, // адрес функции обратного вызова // или идентификатор окна DWORD dwCallbackInstance, // данные для функции обратного вызова DWORD dwFlags); // режим открытия устройства
Параметры функции:
lphWaveOut
Дальний указатель на переменную типа HWAVEIN . В эту переменную будет записан идентификатор устройства ввода, который необходим для выполнения всех операций с устройством. Функция waveOutOpen может быть использована для определения возможности записи звуковых данных в заданном формате (например, нестандартном), в этом случае параметр lphWaveIn может иметь значение NULL. Дополнительно в параметре dwFlags следует установить флаг WAVE_FORMAT_QUERY
wDeviceID
Через параметр wDeviceID приложение должно передать функции waveInOpen номер устройства ввода, которое оно собирается открыть или константу WAVE_MAPPER , определенную в файле mmsystem.h.
В первом случае номер устройства может лежать в пределах от нуля до значения, полученного с помощью функции waveInGetNumDevs.
Если приложение использует константу WAVE_MAPPER, функция waveInOpen пытается самостоятельно выбрать и открыть устройство вывода, подходящее для записи звуковых данных в указанном формате
lpFormat
Через параметр lpFormat приложение должно передать функции waveInOpen адрес заполненной структуры WAVEFORMAT. Мы уже рассказывали вам об этой структуре в предыдущем разделе.
dwCallback
Через параметр dwCallback вы можете передать функции waveInOpen адрес функции обратного вызова. Эту функцию будет вызывать драйвер устройства ввода при возникновении событий, имеющих отношение к записи блока данных. При использовании функции обратного вызова в параметре dwFlags следует установить флаг CALLBACK_FUNCTION.
Можно использовать другой способ извещения приложения о возникновении события, который заключается в посылке сообщений функции окна. Для этого параметр dwCallback должен содержать идентификатор окна. Кроме этого, в параметре dwFlags следует установить флаг CALLBACK_WINDOW
dwCallbackInstance
Идентификатор данных, который передается в функцию обратного вызова. Не используется совместно с флагом CALLBACK_WINDOW
dwFlags
Вы можете указывать в этом поле следующие флаги:
Флаг | Описание |
WAVE_FORMAT_QUERY | Функция waveInOpen вызывается только для проверки возможности использования формата звуковых данных, определенного в структуре WAVEFORMAT |
WAVE_ALLOWSYNC | Этот флаг необходимо использовать для открытия синхронного устройства ввода, во время работы которого все приложения блокируются |
CALLBACK_WINDOW | Для извещения о наступлении событий используется окно, идентификатор которого передается через параметр dwCallback |
CALLBACK_FUNCTION | Для извещения о наступлении событий используется функция обратного вызова, адрес которой передается через параметр dwCallback |
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_NODRIVER
В системе нет нужного для работы с устройством ввода драйвера
MMSYSERR_BADDEVICEID
Указан неправильный номер устройства
MMSYSERR_ALLOCATED
Это устройство уже открыто
MMSYSERR_NOMEM
Для выполнения операции не хватает памяти
WAVERR_BADFORMAT
Указанный формат звуковых данных не поддерживается драйвером устройства ввода
WAVERR_SYNC
Была выполнена попытка открыть синхронное устройство ввода без использования флага WAVE_ALLOWSYNC
После открытия устройства ввода необходимо подготовить один или несколько блоков памяти, в который (или которые) будет записана введенная звуковая информация. Требования к блокам памяти, используемым для записи, такие же, как и требования к блокам памяти, используемым для воспроизведения. Они должны быть заказаны как глобальные с флагами GMEM_MOVEABLE и GMEM_SHARE.
Вы можете заказать один блок (как мы это сделали в приложении WAVE), либо использовать очередь или массив блоков, отдавая блоки драйверу по мере необходимости, переписывая каждый раз содержимое записанного блока в wav-файл.
Перед тем как отдать блок драйверу, его, как и в процессе воспроизведения, надо подготовить, для чего следует воспользоваться функцией waveInPrepareHeader .
Функция waveInPrepareHeader
UINT waveInPrepareHeader( HWAVEIN hWaveIn, // идентификатор устройства LPWAVEHDR lpWaveInHdr, // указатель на структуру WAVEHDR UINT wSize); // размер структуры WAVEHDR
Параметры функции:
hWaveIn
Идентификатор устройства ввода, полученный от функции waveInOpen при открытии устройства
lpWaveInHdr
Через параметр lpWaveInHdr приложение должно передать функции waveInPrepareHeader адрес заполненной структуры WAVEHDR, описывающей блок данных, в который будет записана введенная звуковая информация. Формат этой структуры был описан в предыдущем разделе.
wSize
Поле wSize должно содержать размер структуры WAVEHDR
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
MMSYSERR_NOMEM
Для выполнения операции не хватает памяти
Подготовленный блок памяти следует передать драйверу устройства ввода, вызвав функцию waveInAddBuffer :
Функция waveInAddBuffer
UINT waveInAddBuffer( HWAVEIN hWaveIn, // идентификатор устройства LPWAVEHDR lpWaveInHdr, // указатель на структуру WAVEHDR UINT wSize); // размер структуры WAVEHDR
Параметры функции:
hWaveIn
Идентификатор устройства ввода, полученный от функции waveInOpen при открытии устройства
lpWaveInHdr
Через параметр lpWaveInHdr приложение должно передать функции адрес заполненной структуры WAVEHDR, которая соответствует подготовленному блоку данных
wSize
Поле wSize должно содержать размер структуры WAVEHDR
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение.
В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
MMSYSERR_UNPREPARED
Переданный блок данных не был подготовлен функцией waveOutPrepareHeader
Для того чтобы устройство ввода могло приступить к записи, его надо запустить, вызвав функцию waveInStart :
Функция waveInStart
UINT waveInStart(HWAVEIN hWaveIn); // идентификатор устройства
Параметры функции:
hWaveIn
Идентификатор устройства ввода, полученный от функции waveInOpen при открытии устройства
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
Запись будет продолжаться до тех пор, пока не будет записан весь буфер или пока устройство ввода не будет остановлено функцией waveInStop :
Функция waveInStop
UINT waveInStop(HWAVEIN hWaveIn); // идентификатор устройства
Параметры функции:
hWaveIn
Идентификатор устройства ввода, полученный от функции waveInOpen при открытии устройства
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
Если блок записан до конца или если запись блока остановлена, функция окна, идентификатор которой был указан при открытии устройства через параметр dwCallback, получит сообщение MM_WIM_DONE .
Через параметр wParam сообщения MM_WIM_DONE передается идентификатор устройства, которое было использовано для записи блока. Параметр lParam содержит адрес структуры WAVEHDR, соответствующей записанному блоку.
Если для обработки событий используется функция обратного вызова, она получит аналогичное сообщение с кодом WIM_DONE .
После того как приложение получило сообщение MM_WIM_DONE, оно должно передать блок функции waveInUnprepareHeader, затем разблокировать его функцией GlobalUnlock и при необходимости освободить функцией GlobalFree.
Приведем формат вызова функции waveInUnprepareHeader .
Функция waveInUnprepareHeader
UINT waveOutUnprepareHeader( HWAVEIN hWaveIn, // идентификатор устройства LPWAVEHDR lpWaveInHdr, // указатель на структуру WAVEHDR UINT wSize); // размер структуры WAVEHDR
Параметры функции:
hWaveIn
Идентификатор устройства вывода, полученный от функции waveInOpen при открытии устройства
lpWaveOutHdr
Адрес заполненной структуры WAVEHDR, которая соответствует подготовленному блоку данных
wSize
Параметр wSize должно содержать размер структуры WAVEHDR
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
MMSYSERR_STILLPLAYING
Указанный блок все еще находится в очереди
После завершения работы с устройством ввода его необходимо закрыть, вызвав функцию waveInClose . Через параметр этой функции необходимо передать идентификатор закрываемого устройства ввода.
Функция waveInClose
UINT waveInClose( HWAVEIN hWaveIn); // идентификатор устройства
Параметры функции:
hWaveIn
Идентификатор устройства ввода, полученный от функции waveInOpen при открытии устройства
Возвращаемое значение:
При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки:
MMSYSERR_INVALHANDLE
Указан неправильный идентификатор устройства
MMSYSERR_STILLPLAYING
Очередь данного устройства еще содержит блоки для записи