DirectSound8
-
Borland erwartet Libs im OMF Format, MS nimmt aber COFF.
Also entweder konvertieren oder MS Produkte nutzen.
-
hermes schrieb:
Hallo,
habe nun die Library sowie den Header for DirectSound8, bekomme aber eine
Linkerfehlermeldung:"DSOUND.LIB contians invalid OMF record, type 0x21 (possible COFF)
mittels coff2omf.exe kannst du es konvertieren
btw: weis einer worin der unterschied besteht ?
-
mittels coff2omf.exe kannst du es konvertieren
Danke für den Hinweis, habe ich schon über die Borland Hilfe rausgefunden.
Habe die Library nun convertiert und meinem Projekt hinzugefügt.
Den Header habe ich ebenfalls includiert.Nun kommt die folgenden Linkerfehler:
Unresolved external 'DirectSoundEnumerateA' ....
Unresolved external 'DirectSoundCreate8' ....Im Header sind die die Prototypen als "extern" declariert.
Habe auch schon alle dsound libs dem Projekt hinzugefügt, funktioniert
aber nicht.
-
auch die dxguid.lib?
Ich habe ein Dokument zum Thema DirectSound geschrieben - dabei wird MSVC benutzt - Könntest du vielleicht ein Tutorial schreiben wie man DirectSound mit Borland nutzt - ich würde dann dein Tutorial nehmen und in meinen Artikel einbauen, wenn du nichts dagegen hast - außerdem würde mich das dazu anregen zu zeigen wie man ogg Dateien mit DirectSound abspielt - außerdem könnte ich Gründzüge der Soundsynthese erklären was sicherlich auch sehr interessant ist
-
dxguid.lib habe ich ebenfalls mitgelink, die Fehlermeldung kommt aber immer noch.
Wie schon gesagt habe ich schon alle Libs mitgelinkt.
Bin ein wenig Ratlos.Könntest du vielleicht ein Tutorial schreiben wie man DirectSound mit Borland nutzt
Mach ich gerne, wenn es ersteinmal läuft.
-
Kannst du mal die Libarys unter
http://www.geocities.com/foetsch/borlibs/
testenLink zum Download:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16547Bitte schick mir ne E-Mail mit Erlaubnis das ich es in meinem Artikel verwednen darft, wenn du soweit bist - meine E-Mail: vertexwahn@gmx.de
-
Mit den Libs von Borland funkt es.
Das convertieren der MS Libs hat wohl nicht richtig funktioniert.
Danke
-
Hallo,
bekomme nun bei CreateSoundBuffer den Fehler "OUT OF MEMORY" zurück.
Muss ich nicht vorher Speicher allocieren?HRESULT TForm1::CreateSoundBuffer(void) { WAVEFORMATEX wFormat; DSBUFFERDESC dsbdesc; LPDIRECTSOUNDBUFFER pDsb = NULL; 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 = 22050; 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; HRESULT hr = mySoundObjekt->CreateSoundBuffer(&dsbdesc, &pDsb, NULL); return hr; }
-
Sehe gerade, das ich die Größe des Buffer vergessen habe zu initialisieren.
//---------------------------------------------------------------------------- // 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; // Format ist PCM wFormat.nChannels = 2; // 2 Channels wFormat.nSamplesPerSec = 44100; // 44100 Samples per second wFormat.nBlockAlign = 4; // 4 Bytes per Sample wFormat.nAvgBytesPerSec = wFormat.nSamplesPerSec * wFormat.nBlockAlign; // Bytes per second wFormat.wBitsPerSample = 16; // Bits per Sample dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.lpwfxFormat = &wFormat; // Zeiger auf WAVEFORMATEX dsbdesc.dwBufferBytes = 256000; // 256000 Byte Buffergröße HRESULT hr = mySoundObjekt->CreateSoundBuffer(&dsbdesc, &pDsb, NULL); // Buffer erstellen return hr; }
-
Hallo,
wie schließe ich ein DirectSound Objekt um anschließend ein neues für ein
anderes Sound Device zu erstellen?
-
release, wie jedes com objekt-.-
-
otze schrieb:
release, wie jedes com objekt-.-
Ich habe ingesamt 4 Sound Devices zur Auswahl.
Ich gebe mit einem Button "Start" einen Sinus auf Device 1 aus und
beende die Ausgabe mit einem Button "Stop", wobei ich den Buffer mit
pDsb->Release() schließe, was zu klappen scheint ->DS_OK.Nun wähle ich ein anderes Sound Device aus und erzeuge für dieses
Device ein neues Objekt "hr = DirectSoundCreate8(Device, &mySoundObjekt, NULL)", bei dem Versuch kommt die Fehlermeldung
hr = "ALLOCATED".
Kann es sein, das ich mit Release zwar den Buffer schließe aber das Objekt
immer noch besteht?
-
hermes schrieb:
otze schrieb:
release, wie jedes com objekt-.-
Ich habe ingesamt 4 Sound Devices zur Auswahl.
Ich gebe mit einem Button "Start" einen Sinus auf Device 1 aus und
beende die Ausgabe mit einem Button "Stop", wobei ich den Buffer mit
pDsb->Release() schließe, was zu klappen scheint ->DS_OK.Nun wähle ich ein anderes Sound Device aus und erzeuge für dieses
Device ein neues Objekt "hr = DirectSoundCreate8(Device, &mySoundObjekt, NULL)", bei dem Versuch kommt die Fehlermeldung
hr = "ALLOCATED".
Kann es sein, das ich mit Release zwar den Buffer schließe aber das Objekt
immer noch besteht?Setze nach dem Release doch mal hr = NULL;
EDIT: Ich meine natürlich pDsb*
-
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)