레이블이 FMR & Record인 게시물을 표시합니다. 모든 게시물 표시
레이블이 FMR & Record인 게시물을 표시합니다. 모든 게시물 표시

2010년 5월 18일 화요일

Popup 노이즈


내 귀는 막귀라서 지금까지 popup 노이즈가 뭔지도 몰랐다.
마이크가 켜지는 소리라고 하는데-_-);;;;
디바이스가 켜지면서 팟!! 하고 나는 소리라고 한다.
얘기를 듣고 나서 들어보니까 그런 소리가 나는 것 같기도 하고... - _-);


이것을 처리하기 위한 방법은 두 가지가 있는데, 하나는 하드웨어적 다른 하나는 소프트웨어적인 방법이다.
하드웨어적인 방법은 간단하다.
마이크를 비싸고 좋은 걸 달아서 애초에 노이즈가 생기지 않게 하는 거다.
소프트웨어적인 방법은 마이크로 PCM 데이타가 들어올 때 처음 popup노이즈 부분을 제거하는 방법이다.
buffer의 일정 부분을 잘라버리든가 하는 방법으로..

처음에 이것을 처리할 때,
처음 popup노이즈 부분을 애초에 버퍼에 저장하지 않는 방법을 사용하려고 했지만,
프로세서가 수행되고 있지 않더라도 하위 버퍼에는 계속적으로 PCM 데이타가 들어오고 있으므로 소용이 없었다.
걍 buffer의 앞부분을 버리는게 방법.

2010년 5월 17일 월요일

라디오 주파수 수신 감도 조절


FM라디오 명령어 중에 seek라는 명령이 있는데,
이것이 하는 기능은 수신 가능한 채널을 자동으로 찾아주는 것이다.
device control 명령어로 수행되기에 하드웨어적으로 어떻게 처리되는지는 모르겠으나,
일단 입력값으로 값을 높게 주면 줄 수록 감도가 좋은 것을 받아온다.

즉, 입력값을 높은 값을 줄 수록 선명한 채널을 얻을 수 있지만,
수신 감도가 좋지 않은 채널에 대해서는 스킵 되므로 다양한 채널을 얻을 수 없게 될 수도 있다.
그렇다고 해서 입력값을 너무 작은 숫자를 주면,
다양한 채널을 얻을 수 있지만, 그 중에 청취 가능하지 않은 채널들이 많이 섞일 수 있다.

그래서 적절한 입력 값을 주는 것이 중요한데, 이것은 반복 테스트를 통해서 가능하다. (노가다-_-)

결국 16~17개의 채널을 찾아내는 값으로 설정했다.
여기서 좀 더 높이면 107.7을 잡지 못하길래.. -_-);

2010년 3월 4일 목요일

Wave file 만들기 (2)


mmio 함수들을 이용하여 만들기 귀찮다면, 이전 포스팅을 참고 하시길.

HMMIO hMmio = NULL;
MMCKINFO wavChunk;
MMCKINFO wavSubChunk;
//mm chunk 정보를 저장하기 위한 구조체 변수

MMRESULT mmResult;

WAVEFORMATEX WaveFormat;
WaveFormat.wFormatTag=WAVE_FORMAT_PCM;
WaveFormat.nChannels = 2;
WaveFormat.nSamplesPerSec = 11025;
WaveFormat.wBitsPerSample = 8;
WaveFormat.nBlockAlign = WaveFormat.nChannels*(WaveFormat.wBitsPerSample/8);
WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec*WaveFormat.nBlockAlign;
WaveFormat.cbSize = 0;
//Wave file format을 저장하는 구조체를 선언하고 알맞은 값으로 초기화.
//이 구조체에 대해서는 wave file header를 참고

hMmio = mmioOpen(L"test.wav", NULL,
MMIO_CREATE | MMIO_WRITE | MMIO_EXCLUSIVE |
MMIO_ALLOCBUF | MMIO_EXIST);
//MMIO handle을 받아온다.

if(hMmio == NULL) // 에러 처리 { RETAILMSG(1, (TEXT("fail create wave file\r\n"))); return false; }

ZeroMemory(&wavChunk, sizeof(wavChunk)); //메모리 초기화 wavChunk.fccType = mmioFOURCC('W','A','V','E'); //chunk 정보 입력 mmResult = mmioCreateChunk(hMmio, &wavChunk, MMIO_CREATERIFF); //chunk 생성

if(mmResult != MMSYSERR_NOERROR) // 에러 처리
{ RETAILMSG(1, (TEXT("error mmioCreateChunk (WAVE)\r\n"))); return false; }

//sub chunk 생성
ZeroMemory(&wavSubChunk, sizeof(wavSubChunk)); wavSubChunk.ckid = mmioFOURCC('f','m','t',' '); wavSubChunk.cksize = sizeof(WAVEFORMATEX) + WaveFormat.cbSize; mmResult = mmioCreateChunk(hMmio, &wavSubChunk, 0);
if(mmResult != MMSYSERR_NOERROR) // 에러 처리
{ RETAILMSG(1, (TEXT("error mmioCreateChunk (FMT)\r\n"))); return false; } mmResult = mmioWrite(hMmio, (char*)&WaveFormat, sizeof(WAVEFORMATEX)
+ WaveFormat.cbSize); if(mmResult != MMSYSERR_NOERROR) // 에러 처리
{ RETAILMSG(1, (TEXT("error mmioWrite\r\n"))); return false; } mmResult = mmioAscend(hMmio, &wavSubChunk, 0); if(mmResult != MMSYSERR_NOERROR) // 에러 처리
{ RETAILMSG(1, (TEXT("error mmioAscend\r\n"))); return false; } wavSubChunk.ckid = mmioFOURCC('d','a','t','a'); mmResult = mmioCreateChunk(hMmio, &wavSubChunk, 0); if(mmResult != MMSYSERR_NOERROR) // 에러 처리
{ RETAILMSG(1, (TEXT("error mmioCreateChunk (DATA)\r\n"))); return false; }

DWORD len = 0; len = mmipWrite(hMmio, pBuffer, BUFFERSIZE);  //data를 쓴다.
if(len <= 0) { RETAILMSG(1, (TEXT("error WRITE \r\n"))); return false; }

mmioClose(hMmio,0); //handle close



mmio 함수는 winCE에서는 지원하지 않으며, winmm.dll과 winmm.lib를 포함시켜 주어야 한다.

2010년 2월 26일 금요일

Wave file format

wave file format

offset

size(byte)

field

0

4

"RIFF" or "LIST"

4

4

file size (data size + 40)

8

4

"WAVE"

12

4

"fmr "

16

4

16

20

2

WAVE_FORMAT_PCM

22

2

1 = mono, 2 = strereo

24

4

sample rate

(11kHz: 11025, 22kHz: 22025, 44kHz: 44100)

28

4

bytes per sec

sample rate * channel * (bits per sample/8)

30

2

block align

channel * (bits per sample/8)

32

2

bits per sample (8, 16, ...)

36

4

"data"

40

4

data size


2010년 2월 25일 목요일

Wave file 만들기

winCE에서 winmm.lib를 쓸 수 없는 관계로,, mmio 함수들을 하나도 쓰지 못하고.ㅠㅜ
결국엔 wave file을 손수 만들어 주어야 하는 귀찮음에 봉착하였다.

wave file header 구조에 따라 다음과 같은 구조체를 선언한다.

typedef struct
{
           FOURCC ckID; // 'RIFF'인지 'LIST'인지 넣어준다.
           DWORD dwFileSize; // 전체 file크기 저장 (data크기 + 40)
           FOURCC fccType; // 'WAVE'
           FOURCC subckID; // 'fmr '
           DWORD dwSubChunkSize; // 16
           WORD wFormatTag; // WAVE_FORMAT_PCM
           WORD nChannels; // 1 = mono, 2 = stereo
           DWORD nSamplesPerSec; // 11025, 22050 등등등
           DWORD wBitsPerSample; // 8, 16, 등등등
           WORD nBlockAlign; // nChannels * wBitsPerSample/8
           WORD nAvgBytesPerSec; // nChannels * wBitsPerSample/8 * nSamplesPerSec
           FOURCC datackID; // 'data'
           DWORD dwDataSize; // data크기
} WaveFormChunk;


그리고 이 구조체에 대한 변수를 하나 선언하여 알맞은 값을 넣어주고,
파일의 맨 앞부분에 write한다.

WaveFormChunk WaveHeader;
WaveHeader.ckID = FOURCC_RIFF;
WaveHeader.dwFileSize = m_dwDataLen + 40;
WaveHeader. fccType = MAKEFOURCC('W', 'A', 'V', 'E');
WaveHeader.subckID = MAKEFOURCC('f', 'm', 't', ' ');
WaveHeader.dwSubChunkSize = 16;
WaveHeader. wFormatTag = WAVE_FORMAT_PCM;
WaveHeader. nChannels = 2;//pWaveFormat->nChannels;
WaveHeader. nSamplesPerSec = 11025;//pWaveFormat->nSamplesPerSec;
WaveHeader. wBitsPerSample = 8;//pWaveFormat->wBitsPerSample;
WaveHeader. nBlockAlign = WaveHeader. nChannels * WaveHeader. wBitsPerSample /8;
WaveHeader. nAvgBytesPerSec = WaveHeader. nSamplesPerSec * WaveHeader. nBlockAlign;          
WaveHeader.datackID = MAKEFOURCC('d','a','t','a');
WaveHeader.dwDataSize = m_dwDataLen;

WriteFile(hFile, & WaveHeader, sizeof(WaveFormChunk), &dwSize, NULL);
//파일 입출력 참고 (포스팅보러가기)

그리고 나머지  data를 write하면 wave 파일이 생성된다-_-)/