Newsgroup: it.comp.lang.visual-basic
Titolo: attaccare due file wave in un unico file wave

Devo attaccare due file wave in un unico file wave. Questa volta ho provato
ad usare le directX 8, per la precisione i buffer di directSound. Il codice
che ho scritto funziona bene però solo con un certo tipo di file wave,
quelli con formato 8 bit mono:
 - buffFormat.nChannels = 1   (mono)
 - buffFormat.nBitsPerSample = 8
Ho provato con wave 16 bit e/o stereo ma non funziona con quelli.
PERCHE'?????
Ecco il codice Visual Basic che uso:
'DirectX Variable
Dim mobjDX As DirectX8
Dim mobjDS As DirectSound8
Dim objBuffer As DirectSoundSecondaryBuffer8
Public Sub Initialize(frmInit As Form)
    'Initialize DirectSound
    Set mobjDX = New DirectX8
    Set mobjDS = mobjDX.DirectSoundCreate("")
    'Set the DirectSound object's cooperative level (Priority gives us sole
control)
    mobjDS.SetCooperativeLevel frmInit.hWnd, DSSCL_PRIORITY
End Sub
Public Sub Terminate()
    Set mobjDS = Nothing
    Set mobjDX = Nothing
    Set objBuffer = Nothing
End Sub
'file1,file2,fileMerge are the path and name of the file
Public Sub MergeFile(file1 As String, file2 As String, fileMerge As String)
  Dim buffDesc As DSBUFFERDESC
  Dim newBuffDesc As DSBUFFERDESC
  Dim buffCaps As DSBCAPS
  Dim buffFormat As WAVEFORMATEX
  Dim objBuffer1 As DirectSoundSecondaryBuffer8
  Dim objBuffer2 As DirectSoundSecondaryBuffer8
  Dim glngChunkSize1 As Long 'size of first chunk
  Dim gbytData1() As Byte  'array for first chunk
  Dim glngChunkSize2 As Long 'size of second chunk
  Dim gbytData2() As Byte  'array for second chunk
  buffDesc.lFlags = DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME Or
DSBCAPS_CTRLFREQUENCY
  'put first file in a buffer
  Set objBuffer1 = mobjDS.CreateSoundBufferFromFile(file1, buffDesc)
  'get buffer size
  objBuffer1.GetCaps buffCaps
  glngChunkSize1 = buffCaps.lBufferBytes
  'copy in gbytData1 wave chunk from first buffer
  ReDim gbytData1(glngChunkSize1)
  objBuffer1.ReadBuffer 0, glngChunkSize1, gbytData1(0),
DSBLOCK_ENTIREBUFFER
  'put second file in a buffer
  Set objBuffer2 = mobjDS.CreateSoundBufferFromFile(file2, buffDesc)
  'get buffer size
  objBuffer2.GetCaps buffCaps
  glngChunkSize2 = buffCaps.lBufferBytes
  'copy in gbytData2 wave chunk from second buffer
  ReDim gbytData2(glngChunkSize2)
  objBuffer2.ReadBuffer 0, glngChunkSize2, gbytData2(0),
DSBLOCK_ENTIREBUFFER
  'get buffer format
  objBuffer2.GetFormat buffFormat
  'Set the Wave Format, copying it from second file
  With newbuffdesc.fxFormat
      .nFormatTag = buffFormat.nFormatTag
      .nChannels = buffFormat.nChannels
      .lSamplesPerSec = buffFormat.lSamplesPerSec
      .nBitsPerSample = buffFormat.nBitsPerSample
      .nBlockAlign = buffFormat.nBlockAlign
      .lAvgBytesPerSec = buffFormat.lAvgBytesPerSec
  End With
  newBuffDesc.lFlags = buffDesc.lFlags
  newBuffDesc.guid3DAlgorithm = buffDesc.guid3DAlgorithm
  newBuffDesc.lBufferBytes = glngChunkSize1 + glngChunkSize2
  'Create an empty buffer with previous format
  Set objBuffer = Nothing
  Set objBuffer = mobjDS.CreateSoundBuffer(newBuffDesc)
  'Write the buffer with data
  objBuffer.WriteBuffer 0, glngChunkSize1, gbytData1(0), DSBLOCK_DEFAULT
  objBuffer.WriteBuffer glngChunkSize1 + 1, glngChunkSize2, gbytData2(0),
DSBLOCK_DEFAULT
 'play mergerd file
  objBuffer.Play DSBPLAY_DEFAULT
  'save merged file to disk
  objBuffer.SaveToFile fileMerge
  Set objBuffer1 = Nothing
  Set objBuffer2 = Nothing
End Sub

Mi rispondo da solo. L'inghippo stava qua:
'Write the buffer with data
  objBuffer.WriteBuffer 0, glngChunkSize1, gbytData1(0), DSBLOCK_DEFAULT
  objBuffer.WriteBuffer glngChunkSize1 + 1, glngChunkSize2,
gbytData2(0),DSBLOCK_DEFAULT
Siccome gli array coi dati sono zero based, scrivere glngChunkSize1 + 1 mi
faceva saltare un byte, cioč ci inserivo dentro un byte vuoto. Questo con 8
bit mono significava inserire una piccolissima pausa che era ininfluente,
mentre a 16 bit stereo voleva invertire i canali sx e dx e sfasare tutta la
sequenza di suoni.
Quindi mi č bastato mettere:
'Write the buffer with data
  objBuffer.WriteBuffer 0, glngChunkSize1, gbytData1(0), DSBLOCK_DEFAULT
  objBuffer.WriteBuffer glngChunkSize1, glngChunkSize2,
gbytData2(0),DSBLOCK_DEFAULT
per far funzionare il merge di ogni tipo di file wave.
sero