DirectSound8



  • Kannst Du uns mal sagen, wieso Du einen Crosspost im gleichen Forum machst?!? 🕶



  • du brauchst die dsound.h des DirectX SDKs 8.0 oder höher



  • Hallo,

    versuche das ganze gerade bei Microsoft auf der Homepage zu bekommen, finde
    aber nichts was Libs oder Header angeht.

    Wo außer bei Microsoft bekommt man die Library sowie den Header?



  • Bei Microsoft.

    http://msdn.microsoft.com/downloads/list/directx.asp

    (BTW, seh' gerade daß es schon wieder 'n Update gibt?!?) :xmas2:



  • Hab es gefunden, danke Dir.



  • Hallo,

    habe nun die Library sowie den Header for DirectSound8, bekomme aber eine
    Linkerfehlermeldung:

    "DSOUND.LIB contians invalid OMF record, type 0x21 (possible COFF)



  • 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/
    testen

    Link zum Download:
    http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16547

    Bitte 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)


Anmelden zum Antworten