Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2013, 13:57   #1
Kalibans
 
Регистрация: 15.02.2013
Сообщений: 5
По умолчанию Проблема с записью звука средствами стандартной библиотеки Windows

Здравствуйте. Пишу программу, которая будет получать и обрабатывать данные со звуковой карты в виде значений амплитуд.
Попробовал использовать стандартную библиотеку Windows и столкнулся с проблемой: как я понял - после начала записи управление должно передаться функции обратного вызова, в которой по приходу сообщения MM_WIM_DATA должно произойти освобождение буфера и перенос данных в другое место, откуда уже можно с ними работать. Но проблема в том что переход к функции обратного вызова не происходит.
Буду очень благодарен, если кто-то подскажет в чем я ошибся. Заранее спасибо.

Код:
#include "stdafx.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include <conio.h>

#pragma comment(lib,"winmm.lib") 
#pragma comment(lib,"dsound.lib")

using namespace std;


HWAVEIN hWaveIn;
WAVEFORMATEX WaveFormat;

WAVEHDR WaveHdr;

LPWSTR buff;

void CALLBACK hWnd(HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
	switch (uMsg) 
  { 
    case MM_WIM_DATA: 
		waveInUnprepareHeader(hWaveIn, &WaveHdr, sizeof(WAVEHDR));
		//WaveHdr.lpData - указывают на буфер, где хранять записанные данные.
		//После вызова waveInUnprepareHeader ими можно распоряжаться

		//Тут будут действия с данными

		free(WaveHdr.lpData);
		waveInClose(hWaveIn);

      break; 
  } 
return ;
}



int _tmain(int argc, _TCHAR* argv[])
{
	//Инициализация устройства записи

WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
WaveFormat.nChannels = 1;
WaveFormat.nSamplesPerSec = 16000L;
WaveFormat.nBlockAlign = 2;
WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec*WaveFormat.nBlockAlign;
WaveFormat.wBitsPerSample = 16;
WaveFormat.cbSize = 0;

MMRESULT mmRes = waveInOpen(&hWaveIn, WAVE_MAPPER, &WaveFormat, (DWORD)hWnd, 0L, CALLBACK_WINDOW);

waveInGetErrorText(mmRes, buff, 100);
cout<<buff<<endl;
	////

	//Подготовка буфера
ULONG BufferSize = WaveFormat.nBlockAlign*WaveFormat.nSamplesPerSec*2; //секунды
WaveHdr.lpData = (LPSTR)malloc(BufferSize);
WaveHdr.dwBufferLength = BufferSize;

waveInPrepareHeader(hWaveIn, &WaveHdr, sizeof(WAVEHDR));

waveInAddBuffer(hWaveIn, &WaveHdr, sizeof(WAVEHDR));
	////

	//Запись
waveInStart(hWaveIn);
	////

system("PAUSE");
	return 0;
}
Kalibans вне форума Ответить с цитированием
Старый 01.03.2013, 17:45   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Sample rate от балды не задают - не факт, что железо будет поддерживать.
Смотрите waveInGetDevCaps(), чтоб узнать что поддерживается.
Далее, вы указываете CALLBACK_WINDOW но передаете указатель на фунцкию, а не HWND - используйте CALLBACK_FUNCTION

Последний раз редактировалось waleri; 01.03.2013 в 17:48.
waleri вне форума Ответить с цитированием
Старый 03.03.2013, 11:35   #3
Kalibans
 
Регистрация: 15.02.2013
Сообщений: 5
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Sample rate от балды не задают - не факт, что железо будет поддерживать.
Смотрите waveInGetDevCaps(), чтоб узнать что поддерживается.
Далее, вы указываете CALLBACK_WINDOW но передаете указатель на фунцкию, а не HWND - используйте CALLBACK_FUNCTION
Большое спасибо, эта проблема разрешилась. Вот только не могу теперь понять как оперировать записанными данными. Пытаюсь записать в файл:
Код:
void CALLBACK hWnd(HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
	switch (uMsg) 
 { 
    case MM_WIM_DATA: 
		waveInUnprepareHeader(hWaveIn, &WaveHdr, sizeof(WAVEHDR));
		//WaveHdr.lpData - указывают на буфер, где хранять записанные данные.
		//После вызова waveInUnprepareHeader ими можно распоряжаться

		DWORD writen=0;
		const HANDLE hFile=CreateFile L"test.txt",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,0,0);
		WriteFile(hFile,WaveHdr.lpData,WaveHdr.dwBytesRecorded,&writen,0);
		FlushFileBuffers(hFile);
		CloseHandle(hFile);
		free(WaveHdr.lpData);
		waveInClose(hWaveIn);
      break; 
  }  

return ;
}
Но в файл пишутся кракозябры. Это я где-то ошибся или нужно эти данные как-то расшифровывать? Мне нужно получить просто мгновенные значения амплитуд.
Очень надеюсь на вашу помощь.
Изображения
Тип файла: jpg Безымянный.jpg (670.7 Кб, 139 просмотров)
Kalibans вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с записью RussDragon PHP 3 07.06.2012 16:21
Проблемы с записью звука Master255 Мультимедиа в Delphi 6 18.06.2010 16:53
Обработка текста с мах использованием стандартной библиотеки С++ ИМЕЕТСЯ ИСХОДНИК! RomkaXXI Помощь студентам 0 13.05.2010 00:44
Работа программы с БД с ограниченной учетной записью пользователя Windows Стас БД в Delphi 3 11.12.2009 14:35