Tipp 0142 SecondaryBuffer Read/Write
Autor/Einsender:
Datum:
  Alexander Csadek
16.10.2006
Entwicklungsumgebung: VB.Net 2003
DirectX-Version:   DirectX 9
Ein sinnvoller Einsatz bei Spielen ist mir nicht eingefallen. Nur wenn man ein "Sound"-Programm erstellt, könnten die DirectSound-Funktionen Read und Write interessant werden.
Zu Beginn des Tipps werden 10 verschiedene Sounds geladen, die auch durch Anklicken der Buttons einzeln abgespielt werden. 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 das 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 neuen SecondaryBuffer. Hierfür wird ein neuer SecondaryBuffer erstellt, mit der Grösse aller abzuspielender Sounds. Beim Erzeugen des SecondaryBuffer wird auch das WaveFormat eingestellt. Wenn dies fehlt, bekommt man nicht das gewünschte Ergebnis. Danach werden die Audio-Daten mit der Funktion Read ausgelesen und nacheinander mit der Funktion Write in den anderen SecondaryBuffer geschrieben. Wichtig ist das Nacheinander, denn sonst würde der folgende Sound den vorhergehenden überschreiben.
Anstatt mit einem Byte-Array können die Wav-Daten auch mit einem System.IO.MemoryStream ausgelesen werden. Hierbei ist zu beachten, dass nach dem Read der Cursor vom MemoryStream wieder an den Anfang (BeginOrigin) gesetzt wird.
Der neue Sound kann in diesem Beispiel auch gleich als WAV-Datei abgespeichert werden. Da bei DirectX 9 die Funktion SaveToFile (wie bei DirectX 7 und DirectX 8) nicht mehr zur Verfügung steht, muss dies "manuell" geschehen. Ich habe für dieses Beispiel aus dem Microsoft DirectX 9 SDK Beispiel 'CaptureSound' die Methode CreateRIFF genommen. Mit dieser Methode wird ein entsprechender WAV-Header erzeugt.
Im folgenden Code-Ausschnitt wird nur die Routine für das Abspielen der Ziffernfolge dargestellt.
 
Private Sub cmd_Play_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles cmd_Play.Click
  Dim myDSoundBufferDesc As New BufferDescription
  Dim myBufferCaps As BufferCaps
  Dim intGesamtBytes As Integer
  Dim intLastAdress As Integer
  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, aber dies hätte zur Folge das alle Sounds zur
  'gleichen Zeit abgespielt werden.
  '-> die Sounds sollen nach einander abgespielt werden.
  If Trim(txt_Zahl.Text).Length > 0 Then
    If Not IsNumeric(txt_Zahl.Text) Then Exit Sub
    'feststellen der Länge alles Sounds in Byte
    For i = 1 To txt_Zahl.Text.Length
      myBufferCaps = _
            DSSounds(CInt(Mid(txt_Zahl.Text, i, 1))).Caps()
      intGesamtBytes += myBufferCaps.BufferBytes
    Next
    'auslesen des WaveFormat von einem der Sounds
    'und in den neuen SoundBuffer setzen
    myDSoundBufferDesc.Format = DSSounds(0).Format
    myDSoundBufferDesc.StaticBuffer = True
    'festlegen der Grösse des SoundBuffer's
    myDSoundBufferDesc.BufferBytes = intGesamtBytes
    'erstellen des neuen SoundBuffer's
    If Not DSAll Is Nothing Then DSAll = Nothing
    DSAll = New SecondaryBuffer(myDSoundBufferDesc, DSoundDevice)
    'In dieser Schleife werden die Daten aller Sounds
    'ausgelesen und nacheinander in den neuen SecondaryBuffer
    'geschrieben. Es würde auch mit einem MemoryStream gehen,
    'aber da der neue Sound auch gespeichert werden soll,
    'ist es besser die Daten als Byte-Array zu haben.
    Dim BufferData As Byte() = Nothing
    'Der neue Sound soll gespeichert werden, daher wird eine 
    'WAV Datei mit einem entsprechendem Header erzeugt.
    If chk_Save.Checked Then
      CreateRIFF(Application.StartupPath & "\DTMFTon.wav", _
        DSSounds(0).Format, intGesamtBytes)
    End If
    For i = 1 To txt_Zahl.Text.Length
      myBufferCaps = _
            DSSounds(CInt(Mid(txt_Zahl.Text, i, 1))).Caps()
      'Auslesen der Bytes
      BufferData = _
        CType(DSSounds(CInt(Mid(txt_Zahl.Text, i, 1))).Read(0, _
        GetType(Byte), LockFlag.None, myBufferCaps.BufferBytes), _
        Byte())
      'Schreiben des Byte-Arrays in den neuen Buffer
      DSAll.Write(intLastAdress, BufferData, LockFlag.None)
      intLastAdress += myBufferCaps.BufferBytes
      'und wenn gewünscht auch in das WAV File
      If chk_Save.Checked Then
        Writer.Write(BufferData, 0, BufferData.Length)
      End If
    Next
    'Falls der neue Sound gespeichert werden soll,
    'muss der Writer noch geschlossen werden
    If chk_Save.Checked Then
      Writer.Close()
      Writer = Nothing
      WaveFile = Nothing
    End If
    DSAll.SetCurrentPosition(0)
    DSAll.Play(0, BufferPlayFlags.Default)
  End If
End Sub
 
Hinweis
Um diesen Tipp ausführen zu können, wird die DirectX 9 for Managed Code Runtime benötigt.
Dieses Beispiel funktioniert mit allen DirectX 9.0 SDK Versionen. Erstellt wurde es mit der folgenden Version:
Update DirectX 9.0 SDK (October 2005)
Pfad: C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\Microsoft.DirectX.dll
Laufzeitversion: v1.1.4322
Assemblyversion: 1.0.2902.0
Pfad: C:\WINDOWS\Microsoft.NET\DirectX for Managed Code\1.0.2902.0\Microsoft.DirectX.Direct3D.dll
Laufzeitversion: v1.1.4322
Assemblyversion: 1.0.2902.0

Windows-Version
98/SE
ME
NT
2000
XP
Vista
Win 7


Download  (83 kB) Downloads bisher: [ 238 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

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

Seite empfehlen Bug-Report
Letzte Aktualisierung: Sonntag, 22. Januar 2012