Q&A

  • Wave.cpp 소스를 delphi 코드로 변환작업을 도와 주십시요..
WAVE 을 녹음하고 재생하는 소스인대요

이것을 DELPHI로 변환을 할려구 하는대 안되요...



고수님의 도음을 부탁드립니다....



// Wave.cpp: Implementierung der Klasse CWave.

//

//////////////////////////////////////////////////////////////////////



#include "stdafx.h"



//////////////////////////////////////////////////////////////////////

// Konstruktion/Destruktion

//////////////////////////////////////////////////////////////////////



CWave::CWave()

{

pFmt = pData = NULL;

}



CWave::~CWave()

{

Stop(); // stop playing, recording

delete pFmt; delete pData; // free memory

}



bool CWave::Read(char * fname)

{

HMMIO hmmio; // file handle for open file

MMCKINFO ciParentChunk; // parent chunk information

MMCKINFO ciSubChunk; // subchunk information structure



Stop(); // just in case

delete pFmt; delete pData; // free memory



// wav-Datei f? gepufferte I/O (8 kByte) ?fnen

hmmio = mmioOpen(fname, NULL, MMIO_READ | MMIO_ALLOCBUF);

if(!hmmio) {

MessageBox(NULL, "Failed to open file.", NULL, MB_OK);

return false;

}



// WAVE-Abschnitt suchen

mmioSeek(hmmio, 0, SEEK_SET ); // reset to beginning of file.

ciParentChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');

if (mmioDescend(hmmio, (LPMMCKINFO) &ciParentChunk, NULL, MMIO_FINDRIFF)) {

MessageBox(NULL, "Not a waveform-audio file.", NULL, MB_OK);

mmioClose(hmmio, 0);

return false;

}



// jedes 'Waveform-Audio' enth?t einen 'fmt'- und einen

// 'data'-Abschnitt, zun?hst wird der 'fmt'-Abschnitt betreten

ciSubChunk.ckid = mmioFOURCC('f', 'm', 't', ' ');

if (mmioDescend(hmmio, &ciSubChunk, &ciParentChunk, MMIO_FINDCHUNK)) {

MessageBox(NULL, "Unable to locate 'fmt' chunk.", NULL, MB_OK);

mmioClose(hmmio, 0);

return false;

}



// Speicher f? 'fmt'-Abschnitt vorbereiten

nFmtSize = ciSubChunk.cksize;

pFmt = new BYTE[nFmtSize];

memset(pFmt,NULL,nFmtSize);



// 'fmt'-Abschnitt lesen

if (mmioRead(hmmio, (HPSTR)pFmt, nFmtSize) != nFmtSize) {

MessageBox(NULL, "Error reading 'fmt' chunk.", NULL, MB_OK);

delete pFmt;

mmioClose(hmmio, 0);

return false;

}



// 'fmt'-Abschnitt verlassen

mmioAscend(hmmio, &ciSubChunk, 0);



// 'data'-Abschnitt betreten

ciSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a');

if (mmioDescend(hmmio, &ciSubChunk, &ciParentChunk, MMIO_FINDCHUNK)) {

MessageBox(NULL, "Unable to locate 'data' chunk.", NULL, MB_OK);

delete pFmt;

mmioClose(hmmio, 0);

return false;

}



// Speicher f? 'data'-Abschnitt anlegen

nDataSize = ciSubChunk.cksize;

pData = new BYTE[nDataSize];



// 'data'-Abschnitt lesen

if(mmioRead(hmmio, (HPSTR)pData, nDataSize) != nDataSize) {

MessageBox(NULL, "Error reading 'data' chunk.", NULL, MB_OK);

delete pFmt; delete pData;

mmioClose(hmmio, 0);

return false;

}



// RIFF-Datei schlie?n

mmioClose(hmmio, 0);

return true;

}



bool CWave::Play(HWND hWnd)

{

static WAVEHDR WaveHdr;



if (!pFmt) // nothing to play

return false;

// open waveform-audio driver

Stop();

MMRESULT rc = waveOutOpen(&hwo, 0, (LPWAVEFORMATEX)pFmt,

(DWORD)hWnd, 0L, CALLBACK_WINDOW);

if (rc != MMSYSERR_NOERROR) {

MessageBox(NULL, "Unable to open waveform-audio driver.", NULL, MB_OK);

return false;

}



// configure WAVEHDR

WaveHdr.lpData = (char*) pData;

WaveHdr.dwBufferLength = nDataSize;

WaveHdr.dwFlags = WaveHdr.dwLoops = 0L;



// prepare, write, and unprepre WAVEHDR

waveOutPrepareHeader(hwo, &WaveHdr, sizeof(WAVEHDR));

waveOutWrite(hwo, &WaveHdr, sizeof(WAVEHDR));

return true;

}



void CWave::Stop()

{

waveInReset(hwi);

waveInClose(hwi);

waveOutReset(hwo);

waveOutClose(hwo);

}



CString CWave::Info()

{

CString i = "keine Datei geladen";

WAVEFORMATEX *w= (WAVEFORMATEX*) pFmt;

if (w)

if (w->wFormatTag == WAVE_FORMAT_PCM)

i.Format("Kan?e: %d, nAbtastrate: %d, nSample: %d Bit",

(int) w->nChannels,

(int) w->nSamplesPerSec,

(int) w->wBitsPerSample);

else

i="kann den wave-codec nicht interpretieren";

return i;

}





void CWave::Draw(CDC *dc, CRect rect, long offset, char channel) {

//Rechteck

dc->MoveTo(rect.TopLeft());

dc->LineTo(rect.right,rect.top);

dc->LineTo(rect.BottomRight());

dc->LineTo(rect.left,rect.bottom);

dc->LineTo(rect.TopLeft());



if (!pFmt) return; // nothing to draw



WAVEFORMATEX *w = (WAVEFORMATEX*) pFmt;

int x = rect.left; //x-Position

int y = rect.top+(rect.bottom-rect.top)/2;



dc->MoveTo(x++,y); //Stift setzen



short int value16, max16=0x7FFF; // f? 16 Bit Samples

unsigned char value8, max8=0x7F; // f? 8 Bit Samples



long i=offset*((int)w->nChannels)*((int)w->wBitsPerSample/8);



if ((channel == 'r') && ((int)w->nChannels ==2))

i += w->wBitsPerSample/8;

dc->MoveTo(x++, y);

for (;x<=rect.right; x++) {

if (i>=nDataSize) break; //end of sound

if ((int)w->wBitsPerSample == 16) {

y = rect.top + (rect.bottom-rect.top)/2;

value16= *((short int*)(pData + i));

y -= (int) ((float)value16/max16 * ((rect.bottom-rect.top)/2));

} else {

y = rect.bottom;

value8 = *((unsigned char*)(pData + i));

y -= (int) ((float)value8/max8 * ((rect.bottom-rect.top)/2));

}

dc->LineTo(x,y);

i += ((int)w->nChannels)*((int)w->wBitsPerSample/8);

}



}





bool CWave::Save(CString fname)

{

HMMIO hmmio; // file handle for open file

MMCKINFO ciRiffChunk; // main RIFF chunk information

MMCKINFO ciSubChunk; // subchunk information

MMIOINFO mmioInfo;

MMRESULT rc;



if (!pFmt) return false; // nothing to save



// rename a prev. wav-file (if one exists)

mmioRename(fname, fname+".orig", NULL, 0);



// open the wave file using an internal I/O buffer

memset(&mmioInfo, 0, sizeof(mmioInfo)); // set struct to zero



mmioInfo.fccIOProc = mmioStringToFOURCC("WAV ", 0);

hmmio = mmioOpen((char*) LPCTSTR(fname), &mmioInfo,MMIO_CREATE | MMIO_WRITE | MMIO_ALLOCBUF);

if(!hmmio) {

MessageBox(NULL, "Failed to open file.", NULL, MB_OK);

return false;

}



// attempt to increase the size of the buffer to 128K

mmioSetBuffer(hmmio, NULL, 131072, 0);



// create main 'RIFF' chunk

mmioSeek(hmmio, 0, SEEK_SET); // reset to beginning of file.

ciRiffChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');

ciRiffChunk.cksize = 0L; // mmio will determine corect size

rc = mmioCreateChunk(hmmio, &ciRiffChunk, MMIO_CREATERIFF);



// create 'fmt' chunk

ciSubChunk.ckid = mmioStringToFOURCC("fmt ", 0);

ciSubChunk.cksize = sizeof(WAVEFORMATEX);

rc = mmioCreateChunk(hmmio, &ciSubChunk, 0);

rc = mmioWrite(hmmio, (char*) pFmt, sizeof(WAVEFORMATEX));





// ascend out of 'fmt' chunk back to the main 'RIFF' chunk

rc = mmioAscend(hmmio, &ciSubChunk, 0);



// create 'data' chunk

// if the cksize is incorrect, when we ascend out of the chunk,

// the cksize will be updated to it's actual size

ciSubChunk.ckid = mmioStringToFOURCC("data", 0);

ciSubChunk.cksize = nDataSize;

rc = mmioCreateChunk(hmmio, &ciSubChunk, 0);



// okay, now lets write the data to the buffer

rc = mmioWrite(hmmio, (char*) pData, nDataSize);



// ascend out of 'data' chunk back to the main 'RIFF' chunk

// this corrects the chunk length if not correctly

// specified when the chunk was created.

rc = mmioAscend(hmmio, &ciSubChunk, 0);



// ascend out of the main 'RIFF' chunk

rc = mmioAscend(hmmio, &ciRiffChunk, 0);



// flush buffer and close file

rc = mmioFlush(hmmio, 0);

rc = mmioClose(hmmio, 0);



// you have to check rc after each mmio-Call !!!

return true;

}



bool CWave::Record(HWND hWnd) {

static WAVEHDR WaveHdr;

if (!pFmt) return false; //no parameters



//open waveform-driver

MMRESULT rc = waveInOpen(&hwi, 0, (LPWAVEFORMATEX) pFmt,(DWORD) hWnd, 0L, CALLBACK_WINDOW);

if (rc != MMSYSERR_NOERROR) {

AfxMessageBox("Unable to open audio driver");

return false;

}



WaveHdr.lpData=(char*) pData;

WaveHdr.dwBufferLength=nDataSize;

WaveHdr.dwFlags = WaveHdr.dwLoops = 0;



waveInPrepareHeader(hwi,&WaveHdr, sizeof(WaveHdr));

waveInAddBuffer(hwi,&WaveHdr, sizeof(WaveHdr));

waveInStart(hwi);

return true;

}



bool CWave::Create(int nSamplesPerSec, int wBitsPerSample,

int nChannels, int nSeconds) {

// Test, ob Parameter plausibel sind

if (((nSamplesPerSec != 8000) && (nSamplesPerSec != 11025) &&

(nSamplesPerSec != 22050) && (nSamplesPerSec != 44100)) ||

((nChannels != 1) && (nChannels != 2)) ||

((wBitsPerSample != 8) && (wBitsPerSample != 16)))

return false;



Stop();

delete pFmt; delete pData;



//Speicher f? fmt-Abschnitt vorbereiten

WAVEFORMATEX *w = new WAVEFORMATEX;

pFmt = (BYTE*) w;

nFmtSize = sizeof(WAVEFORMATEX);

w->wFormatTag = WAVE_FORMAT_PCM;

w->nChannels= nChannels;

w->nSamplesPerSec=nSamplesPerSec;

w->wBitsPerSample=wBitsPerSample;

w->nBlockAlign=nChannels*wBitsPerSample/8;

w->nAvgBytesPerSec=nSamplesPerSec*w->nBlockAlign;

w->cbSize=0;



//Speicher f? data-Abschnitt

nDataSize=w->nAvgBytesPerSec*nSeconds;

pData = new BYTE[nDataSize];

memset(pData,NULL,nDataSize);



return true;

}





0  COMMENTS