H
Hier mein Code.
unsigned char cnt;
LPGUID Device;
LPGUID Device1;
LPGUID Device2;
LPGUID Device3;
LPGUID Device4;
AnsiString asDevice1;
AnsiString asDevice2;
AnsiString asDevice3;
AnsiString asDevice4;
LPDIRECTSOUND8 mySoundObjekt;
LPVOID lpvWrite;
DWORD dwLength;
TForm1 *Form1;
//----------------------------------------------------------------------------
// Konstruktor
//----------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc,NULL); //Callback init
Device = Device1; //Ausgabe auf Device1
Edit1->Text = asDevice1; //Device in Editfenster anzeigen
}
//------------------------------------------------------------------------------
// DirectSoundEnumerate Callback
//------------------------------------------------------------------------------
bool CALLBACK DSEnumProc(LPGUID lpGuid,LPCSTR lpcstrDescription,LPCSTR lpcstrModule,LPVOID lpContext)
{
if(cnt == 0)
{
Device1 = lpGuid;
Form1->D1->Caption = lpcstrDescription;
asDevice1 = lpcstrDescription;
cnt++;
return true;
}
else if(cnt == 1)
{
Device2 = lpGuid;
Form1->D2->Caption = lpcstrDescription;
asDevice2 = lpcstrDescription;
cnt++;
return true;
}
else if(cnt == 2)
{
Device3 = lpGuid;
Form1->D3->Caption = lpcstrDescription;
asDevice3 = lpcstrDescription;
cnt++;
return true;
}
else if(cnt == 3)
{
Device4 = lpGuid;
Form1->D4->Caption = lpcstrDescription;
asDevice4 = lpcstrDescription;
cnt++;
return false;
}
return false;
}
//------------------------------------------------------------------------------
// Create Sound Objekt
//------------------------------------------------------------------------------
bool TForm1::CreateSoundObjekt(void)
{
HRESULT hr = DirectSoundCreate8(Device, &mySoundObjekt, NULL);
if(hr != DS_OK)
{
ShowError("DIRECT_SOUND_CREATE ERROR",hr); // Hier kommt es zu dem Fehler "ALLOCATED"
return 0;
}
else
{
if(mySoundObjekt->SetCooperativeLevel(Application->Handle,DSSCL_PRIORITY) != DS_OK)
{
Application->MessageBox("SETCOOPERATIVELEVEL","Error",MB_OK | MB_ICONERROR);
return 0;
}
else
{
HRESULT hr = CreateSoundBuffer();
if(hr != DS_OK)
{
ShowError("CREATE_SOUND_BUFFER ERROR",hr);
return 0;
}
}
}
return 1;
}
//----------------------------------------------------------------------------
// Create a Soundbuffer
//----------------------------------------------------------------------------
LPDIRECTSOUNDBUFFER pDsb = NULL;
HRESULT TForm1::CreateSoundBuffer(void)
{
WAVEFORMATEX wFormat;
DSBUFFERDESC dsbdesc;
memset(&wFormat, 0, sizeof(WAVEFORMATEX)); //Structur löschen
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); //Structur löschen
wFormat.wFormatTag = WAVE_FORMAT_PCM;
wFormat.nChannels = 2;
wFormat.nSamplesPerSec = 44100;
wFormat.nBlockAlign = 4;
wFormat.nAvgBytesPerSec = wFormat.nSamplesPerSec * wFormat.nBlockAlign;
wFormat.wBitsPerSample = 16;
dsbdesc.dwSize = sizeof(DSBUFFERDESC); //Grösse
dsbdesc.dwBufferBytes = DSBSIZE_MAX;//3 * wFormat.nAvgBytesPerSec;
dsbdesc.lpwfxFormat = &wFormat;
dsbdesc.dwBufferBytes = 256000;
HRESULT hr = mySoundObjekt->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);
return hr;
}
//----------------------------------------------------------------------------
// Copy to Buffer and Play
//----------------------------------------------------------------------------
bool TForm1::CopyToBufferAndPlay(LPGUID Device)
{
HRESULT hr = pDsb->Lock(0,0,&lpvWrite,&dwLength,NULL,NULL,DSBLOCK_ENTIREBUFFER);
if(hr != DS_OK)
{
ShowError("LOCK ERROR",hr);
return 0;
}
memcpy(lpvWrite, SoundBuffer, dwLength);
hr = pDsb->Unlock(lpvWrite, dwLength, NULL, 0);
if(hr != DS_OK)
{
ShowError("UNLOCK ERROR",hr);
return 0;
}
hr = pDsb->Play(0,0,DSBPLAY_LOOPING);
if(hr != DS_OK)
{
ShowError("PLAY SOUND ERROR",hr);
return 0;
}
return 1;
}
//------------------------------------------------------------------------------
// Fehlerausgabe
//------------------------------------------------------------------------------
void TForm1::ShowError(char* text,HRESULT hr)
{
switch(hr)
{
case DSERR_ALLOCATED:
Application->MessageBox("ALLOCATED",text,MB_OK | MB_ICONERROR);
break;
case DSERR_BADFORMAT:
Application->MessageBox("BADFORMAT",text,MB_OK | MB_ICONERROR);
break;
case DSERR_BUFFERTOOSMALL:
Application->MessageBox("BUFFER_TO_SMALL",text,MB_OK | MB_ICONERROR);
break;
case DSERR_CONTROLUNAVAIL:
Application->MessageBox("CONTROLUNAVAIL",text,MB_OK | MB_ICONERROR);
break;
case DSERR_DS8_REQUIRED:
Application->MessageBox("DS8_REQUIRED",text,MB_OK | MB_ICONERROR);
break;
case DSERR_INVALIDCALL:
Application->MessageBox("INVALID_CALL",text,MB_OK | MB_ICONERROR);
break;
case DSERR_INVALIDPARAM:
Application->MessageBox("INVALID_PARAM",text,MB_OK | MB_ICONERROR);
break;
case DSERR_NOAGGREGATION:
Application->MessageBox("NOAGGREGATION",text,MB_OK | MB_ICONERROR);
break;
case DSERR_OUTOFMEMORY:
Application->MessageBox("OUT_OF_MEMORY",text,MB_OK | MB_ICONERROR);
break;
case DSERR_UNINITIALIZED:
Application->MessageBox("UNINITIALIZED","CREATESOUNDBUFFER ERROR",MB_OK | MB_ICONERROR);
break;
case DSERR_UNSUPPORTED:
Application->MessageBox("UNSUPPORTED","CREATESOUNDBUFFER ERROR",MB_OK | MB_ICONERROR);
break;
case DSERR_NODRIVER:
Application->MessageBox("NO_DRIVER",text,MB_OK | MB_ICONERROR);
break;
case DSERR_BUFFERLOST:
Application->MessageBox("BUFFER_LOST",text,MB_OK | MB_ICONERROR);
break;
case DSERR_PRIOLEVELNEEDED:
Application->MessageBox("PRIO_LEVEL_NEEDED",text,MB_OK | MB_ICONERROR);
break;
default:
Application->MessageBox("ERROR NOT FOUND",text,MB_OK | MB_ICONERROR);
break;
}
}
//------------------------------------------------------------------------------
// Create Sinus
//------------------------------------------------------------------------------
void TForm1::CreateSinus(void)
{
static unsigned int V = 5000;
static float frequenz = 500;
static unsigned int periode;
SoundBuffer = new unsigned int[256000];
float time = 0;
unsigned int x = 0;
periode =(1/frequenz)/22.73E-6;
for(unsigned int i = 0; i < 132000; i++)
{
SoundBuffer[i] = (sin(6.28*frequenz*time)*5000) + 0;
time += 22.73E-6;
x++;
if(x >periode)
{
time = 0;
x = 0;
}
}
return;
}
//------------------------------------------------------------------------------
// Create White Noise
//------------------------------------------------------------------------------
void TForm1::CreateWhiteNoise(void)
{
SoundBuffer = new unsigned int[256000];
for(unsigned int i = 0; i < 132000; i++)
{
SoundBuffer[i] = rand()%65536-32768;
}
return;
}
//------------------------------------------------------------------------------
// Menupunkt Device1 ausgewählt
//------------------------------------------------------------------------------
void __fastcall TForm1::D1Click(TObject *Sender)
{
D1->Checked = true; // Markieren
D2->Checked = false; // Markierung aufheben
D3->Checked = false; // Markierung aufheben
D4->Checked = false; // Markierung aufheben
Edit1->Text = asDevice1; // Ausgewähltes Device1 in Editfenster anzeigen
Device = Device1; // Device1 nach LPGUID Device;
}
//------------------------------------------------------------------------------
// Menupunkt Device2 ausgewählt
//------------------------------------------------------------------------------
void __fastcall TForm1::D2Click(TObject *Sender)
{
D1->Checked = false; // Das gleiche fpür Device2
D2->Checked = true; //........
D3->Checked = false;
D4->Checked = false;
Edit1->Text = asDevice2;
Device = Device2;
}
//------------------------------------------------------------------------------
// Menupunkt Device3 ausgewählt
//------------------------------------------------------------------------------
void __fastcall TForm1::D3Click(TObject *Sender)
{
D1->Checked = false; // Das gleiche fpür Device3
D2->Checked = false; //........
D3->Checked = true;
D4->Checked = false;
Edit1->Text = asDevice3;
Device = Device3;
}
//------------------------------------------------------------------------------
// Menupunkt Device4 ausgewählt
//------------------------------------------------------------------------------
void __fastcall TForm1::D4Click(TObject *Sender)
{
D1->Checked = false; // Das gleiche fpür Device4
D2->Checked = false; //....
D3->Checked = false;
D4->Checked = true;
Edit1->Text = asDevice4;
Device = Device4;
}
//------------------------------------------------------------------------------
// Ausgabe Starten
//------------------------------------------------------------------------------
void __fastcall TForm1::StartButtonClick(TObject *Sender)
{
StopButton->Enabled = true;
StartButton->Enabled = false;
if(!CreateSoundObjekt()) // Objekt erstellen, Buffer erstellen
{
Application->Terminate();
return;
}
if(WaveSelectButton->Caption == "Sinus")
{
CreateSinus(); // Buffer mit Sinus füllen
}
else
{
CreateWhiteNoise(); // Buffer mit WhiteNoise füllen
}
if(!CopyToBufferAndPlay(Device)) // Buffer kopieren und ausgeben
{
Close();
}
}
//------------------------------------------------------------------------------
// Ausgabe Stoppen
//------------------------------------------------------------------------------
void __fastcall TForm1::StopButtonClick(TObject *Sender)
{
StopButton->Enabled = false;
StartButton->Enabled = true;
HRESULT hr = pDsb->Stop(); //Stop
if(hr != DS_OK) //Fehlerbehandlung
{
ShowError("STOP",hr); //Eventuellen Fehler ausgeben
Close(); //Application beenden
}
hr = pDsb->Release(); //Buffer Löschen
if(hr != DS_OK) //Fehlerbehandlung
{
ShowError("RELEASE",hr); //Eventuellen Fehler ausgeben
Close(); //Application beenden
}
}
//------------------------------------------------------------------------------
// Select WaveForm
//------------------------------------------------------------------------------
void __fastcall TForm1::WaveSelectButtonClick(TObject *Sender)
{
if(WaveSelectButton->Caption == "Sinus")
{
WaveSelectButton->Caption = "Noise";
}
else
{
WaveSelectButton->Caption = "Sinus";
}
}
//------------------------------------------------------------------------------
// Form Close
//------------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete SoundBuffer; //Allocierten Speicher Freigeben
}
Wie schon gesagt, beim ersten Starten wird auf Device1 oder dem von mir
ausgewählten Device ausgegeben.
Mit Stop wird mit der Buffer wieder Freigegeben, wenn ich nun über das Main
Menu ein anderes Device auswähle und ich mit start das Objekt anlegen will
kommt die Fehlermeldung "ALLOCATED" (In der Funktion CreateSoundObjekt)