Tipp 0432 Read- und WriteBuffer
Autor/Einsender:
Datum:
  Alexander Csadek
12.01.2005
Entwicklungsumgebung:
DirectX-Version:
  VB 6
DirectX 8
Ein sinnvoller Einsatz bei Spielen ist mir nicht eingefallen. Nur wenn man ein Sound-Programm erstellt, könnten die DirectSound-Funktionen Read- und WriteBuffer interessant werden.
Zu Beginn des Tipps werden 10 verschiedene Sounds geladen, die auch durch Anklicken der Buttons einzeln abgespielt werden können. Die Ziffern der Buttons entsprechen den 10 verschiedenen Sounds.
Um die durch das Anklicken entstandene Ziffernfolge nach einander abspielen zu können, muss man nicht eine Routine schreiben, die prüft, ob nun einer der Sounds aus der Ziffernfolge schon abgespielt wurde oder nicht, und darauf wartet bis der nächste abgespielt werden kann.
Natürlich könnte man auch gleich direkt die entsprechenden Sounds abspielen lassen, aber das hätte zur Folge, dass alle Sounds gleichzeitig abgespielt werden - sie sollen aber nacheinander abgespielt werden.
Es geht auch anders; man liest die Audio-Daten der entsprechenden Sounds aus und schreibt sie nacheinander in einen anderen SoundBuffer. Hierfür wird ein neuer DirectSoundSecondaryBuffer8 erstellt und ein ByteArray angelegt, mit der Größe aller abzuspielender Sounds. Im Gegensatz zu DirectSound von DirectX 7 wird bei DirectX 8 das Wave-Format nicht beim Erstellen des SoundBuffers direkt angegeben und muss in der Buffer-Description (SoundBuffer-Beschreibung) angegeben werden. Wenn dies fehlt bekommt man nicht das gewünschte Ergebnis. Danach werden die Audio-Daten mit der Funktion ReadBuffer ausgelesen und nacheinander in das ByteArray geschrieben. Wichtig ist das Nacheinander, denn sonst würde der folgende Sound den vorhergehenden überschreiben.
Sind alle Sounds ausgelesen worden, wird das ByteArray in den neu erstellten SoundBuffer geschrieben. Dies geschieht mit der DirectSound-Funktion WriteBuffer. Der SoundBuffer wird dann abgespielt.
Zu guter letzt kann die Ziffernfolge auch als WAV-Datei abgespeichert werden. DirectSound bietet hierfür die Funktion SaveToFile an.
Im Gegensatz zu DirectDraw braucht man bei DirectSound die Objekte nicht zu sperren bevor man direkt auf die Daten zugreifen kann. Auch das Entsperren entfällt bei DirectSound.
Im folgenden Code-Ausschnitt wird nur die Routine für das Abspielen der Ziffernfolge dargestellt.
 
Private Sub cmd_Play_Click()
  Dim dsBDesc As DSBUFFERDESC
  Dim wfx As WAVEFORMATEX
  Dim GesamtByteBlock() As Byte
  Dim myDSBCAPS As DSBCAPS
  Dim lngGesamtBytes As Long
  Dim lngLastAdress As Long
  Dim i As Integer

  'Den eingegebenen Ziffern entsprechend werden die Sounds
  'eingelesen und in einen neuen SoundBuffer geschrieben.
  'Natürlich könnte man auch direkt die entsprechenden
  'Sounds abspielen, dies hätte aber Folge, dass alle
  'Sounds zur gleichen Zeit abgespielt werden -> die
  'Sounds sollen aber nach einander abgespielt werden.

  If Len(Trim(txt_Zahl.Text)) > 0 Then
    If Not IsNumeric(txt_Zahl.Text) Then Exit Sub
    'Feststellen der Länge alles Sounds in Byte
    For i = 1 To Len(txt_Zahl.Text)
      dsSounds(CInt(Mid(txt_Zahl.Text, i, 1))).GetCaps myDSBCAPS
      lngGesamtBytes = lngGesamtBytes + myDSBCAPS.lBufferBytes
    Next

    'Festlegen der Grösse des SoundBuffer's
    dsBDesc.lBufferBytes = lngGesamtBytes

    'Da alle Sounds gleich sind, bis auf die Grösse, können die
    'Flags von irgend einem der 10 Sounds genommen werden
    dsBDesc.lFlags = myDSBCAPS.lFlags

    'Auslesen des WaveFormatX von einem der Sounds
    'und in den neuen SoundBuffer setzen
    dsSounds(0).GetFormat wfx
    dsBDesc.fxFormat = wfx

    'Erstellen des neuen SoundBuffer's
    Set dsAll = Nothing
    Set dsAll = DS8.CreateSoundBuffer(dsBDesc)

    'In dieser Schleife werden die Daten aller Sounds ausgelesen
    'und nach einander in das Array of Bytes geschrieben
    ReDim GesamtByteBlock(lngGesamtBytes)
    For i = 1 To Len(txt_Zahl.Text)
      dsSounds(CInt(Mid(txt_Zahl.Text, i, 1))).GetCaps myDSBCAPS

      'Auslesen der Bytes
      dsSounds(CInt(Mid(txt_Zahl.Text, i, 1))).ReadBuffer 0, _
        myDSBCAPS.lBufferBytes, GesamtByteBlock(lngLastAdress), _
              DSBLOCK_DEFAULT
      lngLastAdress = lngLastAdress + myDSBCAPS.lBufferBytes
    Next

    'Schreiben des gesamten Array of Bytes in den SoundBuffer
    dsAll.WriteBuffer 0, lngGesamtBytes, GesamtByteBlock(0), _
              DSBLOCK_DEFAULT

    'Abspeichern der Ziffernfolge als WAV-Datei
    If chk_Save.Value = 1 Then
      dsAll.SaveToFile App.Path & "\DTMFTon.wav"
    End If
    dsAll.Play DSBPLAY_DEFAULT
  End If
End Sub
 
Hinweis
Um dieses Beispiel ausführen zu können, wird die DirectX 8 for Visual Basic Type Library benötigt (siehe dazu die Erläuterungen in der DirectX-Rubrik).

Windows-Version
95
98/SE
ME
NT
2000
XP
Vista
Win 7
VB-Version
VBA 5
VBA 6
VB 4/16
VB 4/32
VB 5
VB 6


Download  (51 kB) Downloads bisher: [ 286 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

Startseite | Projekte | Tutorials | API-Referenz | VB-/VBA-Tipps | Komponenten | Bücherecke | VB/VBA-Forum | VB.Net-Forum | DirectX-Forum | Foren-Archiv | DirectX | VB.Net-Tipps | Chat | Spielplatz | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report
Letzte Aktualisierung: Sonntag, 15. Mai 2011