Fichiers Wave

Programmation d'applications complexes
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Fichiers Wave

Message par Dr. Dri »

Je trouve la lib Sound très (très) limitée... Voila pourquoi j'ai voulu voir comment ca se passait dans le FreeSoundEditor de ZapMan http://www.freesoundeditor.com/

Je suis tombé la page de documentation sur le format wave (qu'on trouve aussi en téléchargement). A partir de ca j'ai fait le jeu de fonctions ci-dessous

Avec un petit exemple d'utilisation que vous pouvez trouver scope.zip
Image
Image
Bien entendu je ne compte pas m'arrêter là et j'espère bien corriger les bugs présents et ajouter tout plein d'autres fonctions ^^

Code : Tout sélectionner

;***********************************************
;* Echange le contenu de deux zones de mémoire *
;***********************************************

Procedure Swap(*a.l, *b.l, Size.l)
  Protected *c.l
  If *a <> #NULL And *b <> #NULL
    *c = AllocateMemory(Size)
    If *c <> #NULL
      CopyMemory(*a, *c, Size)
      CopyMemory(*b, *a, Size)
      CopyMemory(*c, *b, Size)
      FreeMemory(*c)
    EndIf
  EndIf
EndProcedure

;***********************************
;* Déclaration des structures Wave *
;***********************************

Structure WaveFileHeader
  dwRiff.l
  dwSize.l
  dwWave.l
EndStructure

Structure WaveChunk
  dwTag.l
  dwSize.l
EndStructure

Structure WaveFormatChunk
  dwFormat.l
  dwSize.l
  wFormatTag.w
  wChannels.w
  dwSamplesPerSec.l
  dwAvgBytesPerSec.l
  wBlockAlign.w
  wBitsPerSample.w
EndStructure

Structure WaveDataChunk
  dwData.l
  dwSize.l
EndStructure

Structure WaveFile
  ;Header
  dwRiff.l
  dwSize.l
  dwWave.l
  ;Format
  dwFormat.l
  dwFormatSize.l
  wFormatTag.w
  wChannels.w
  dwSamplesPerSec.l
  dwAvgBytesPerSec.l
  wBlockAlign.w
  wBitsPerSample.w
  ;Data
  dwData.l
  dwDataSize.l
EndStructure

;******************************************
;* Déclaration des structures DirectSound *
;******************************************

Structure WaveFormatEx
  wFormatTag.w
  nChannels.w
  nSamplesPerSec.l
  nAvgBytesPerSec.l
  nBlockAlign.w
  wBitsPerSample.w
  cbSize.w
EndStructure

Structure DSBufferDesc 
  dwSize.l
  dwFlags.l
  dwBufferBytes.l
  dwReserved.l
  *lpwfxFormat
  guid3DAlgorithm.Guid
EndStructure

Structure DirectSoundWave Extends WaveFile
  *lpDataSection.l
  ;DirectSound
  Sound.IDirectSoundBuffer8
  PrimaryBuffer.IDirectSoundBuffer
  DirectSound8.IDirectSound8
EndStructure

;***********************************
;* Déclaration des constantes Wave *
;***********************************

#Wave_Chunk_Riff   = 'FFIR'
#Wave_Chunk_Wave   = 'EVAW'
#Wave_Chunk_Format = ' tmf'
#Wave_Chunk_Data   = 'atad'

#Wave_Sample_Raw     = %0000
#Wave_Sample_Percent = %0001
#Wave_Sample_Left    = %0010
#Wave_Sample_Right   = %0100

#Wave_Frequency_Min =   1000
#Wave_Frequency_Max = 100000

Enumeration 0
  #Wave_Offset_Sample
  #Wave_Offset_Time
EndEnumeration

Enumeration 1
  #Wave_Channels_Mono
  #Wave_Channels_Stereo
EndEnumeration

Enumeration 1
  #Wave_Depth_8bits
  #Wave_Depth_16bits
  #Wave_Depth_24bits
  #Wave_Depth_32bits
EndEnumeration

#Wave_Depth_Max = #PB_Compiler_EnumerationValue - 1

;******************************************
;* Déclaration des constantes DirectSound *
;******************************************

#DS_OK = 0

Enumeration 1
  #DSSCL_Normal
  #DSSCL_Priority
  #DSSCL_Exclusive
  #DSSCL_WritePrimary
EndEnumeration

Enumeration 1
  #DSBPlay_Looping
  #DSBLock_EntireBuffer
EndEnumeration

#DSBCaps_LocSoftware   = $08
#DSBCaps_CtrlFrequency = $20
#DSBCaps_CtrlPan       = $40
#DSBCaps_CtrlVolume    = $80

DataSection
  IID_DirectSoundBuffer8:
  Data.l $6825A449
  Data.w $7524, $4D82
  Data.b $92, $0F, $50, $E3
  Data.b $6A, $B3, $AB, $1E
EndDataSection

;**************************************
;* Déclaration des variables globales *
;**************************************

Global DS_Library

;**********************************
;* Déclaration des fonctions Wave *
;**********************************

Declare.l InitWave()

Declare.l CatchWave (WindowID.l, *wfh.WaveFileHeader, Length.l)
Declare.l IsWave    (*dsw.DirectSoundWave)
Declare.l LoadWave  (WindowID.l, Location.s)
Declare.l SaveWave  (*dsw.DirectSoundWave, Location.s)
Declare.l FreeWave  (*dsw.DirectSoundWave)
Declare.l CloneWave (WindowID.l, *dsw.DirectSoundWave)
Declare.l CreateWave(WindowID.l, Depth.l, Frequency.l, Samples.l, Channels.l)

Declare.l WaveChannels    (*dsw.DirectSoundWave)
Declare.l WaveFrequency   (*dsw.DirectSoundWave)
Declare.l WaveDepth       (*dsw.DirectSoundWave)
Declare.l WaveSamples     (*dsw.DirectSoundWave)
Declare.l WaveLength      (*dsw.DirectSoundWave)
Declare.l WaveSaturation  (*dsw.DirectSoundWave)
Declare.l WaveSamplingRate(*dsw.DirectSoundWave)
Declare.l WaveSample      (*dsw.DirectSoundWave, Position.l, Mode.l)
Declare.l WaveSamplePos   (*dsw.DirectSoundWave, Time.l)

Declare.l PlayWave        (*dsw.DirectSoundWave, Looping.l)
Declare.l StopWave        (*dsw.DirectSoundWave)
Declare.l PauseWave       (*dsw.DirectSoundWave)
Declare.l ResumeWave      (*dsw.DirectSoundWave)
Declare.l ReverseWave     (*dsw.DirectSoundWave)
Declare.l ConvertWave     (*dsw.DirectSoundWave, NewValue.l, Type.l)
Declare.l ConvertWaveDepth(WindowID.l, *dsw.DirectSoundWave, Depth)
Declare.l MixWaves        (*dsw1.DirectSoundWave, *dsw2.DirectSoundWave, Offset.l, Mode.l)

;*********************************
;* Définition des fonctions Wave *
;*********************************

Procedure.l InitWave()
  If DS_Library = #Null Or IsLibrary(DS_Library) = #False
    DS_Library = OpenLibrary(#PB_Any, "dsound.dll")
  EndIf
  ProcedureReturn DS_Library
EndProcedure

Procedure.l CatchWave(WindowID.l, *wfh.WaveFileHeader, Length)
  Protected Catch.l, ids8.IDirectSound8, dsbd.DSBufferDesc, idsb.IDirectSoundBuffer
  Protected wfx.WaveFormatEx, *wfc.WaveFormatChunk, *wdc.WaveDataChunk, *wf.WaveFile
  Protected *wc.WaveChunk, Offset.l, HasFormat.l, HasData.l, BytesPerSample.l
  Protected WaveSize.l, tidsb.IDirectSoundBuffer, idsb8.IDirectSoundBuffer8
  Protected lpWrite.l, dwLength.l, *dsw.DirectSoundWave
  If InitWave()
    If CallFunction(DS_Library, "DirectSoundCreate8", #Null, @ids8, #Null) = #DS_OK
      If ids8\SetCooperativeLevel(WindowID, #DSSCL_Normal) = #DS_OK
        ;-a corriger
        dsbd\dwSize        = SizeOf(DSBufferDesc)
        dsbd\dwFlags       = 1
        dsbd\dwBufferBytes = #Null
        dsbd\lpwfxFormat   = #Null
        
        ;Extraction des chunks
        If ids8\CreateSoundBuffer(dsbd, @idsb, #Null) = #DS_OK
          If *wfh\dwRiff = #Wave_Chunk_Riff And *wfh\dwWave = #Wave_Chunk_Wave
            If *wfh\dwSize + OffsetOf(WaveFileHeader\dwWave) = Length
              
              Offset = SizeOf(WaveFileHeader)
              *wc = *wfh + Offset
              
              Offset + SizeOf(WaveChunk)
              If Length - Offset < *wc\dwSize
                Offset = Length
              EndIf
              
              While Offset < Length
                If HasFormat = #False And *wc\dwTag = #Wave_Chunk_Format
                  *wfc = *wc
                  If *wfc\dwSize + SizeOf(WaveChunk) > SizeOf(WaveFormatChunk)
                    *wfc\dwSize = SizeOf(WaveFormatChunk) - SizeOf(WaveChunk)
                  EndIf
                  BytesPerSample = *wfc\wBitsPerSample >> 3
                  If *wfc\wFormatTag = #Wave_Format_PCM
                    If BytesPerSample >= 1 And BytesPerSample <= 4
                      If *wfc\wChannels = #Wave_Channels_Mono Or *wfc\wChannels = #Wave_Channels_Stereo
                        If *wfc\dwSamplesPerSec >= #Wave_Frequency_Min And *wfc\dwSamplesPerSec <= #Wave_Frequency_Max
                          HasFormat = #True
                          ;Recalcule les données calculées par sécurité
                          *wfc\wBlockAlign = BytesPerSample * *wfc\wChannels
                          *wfc\dwAvgBytesPerSec = *wfc\dwSamplesPerSec * *wfc\wBlockAlign
                        EndIf
                      EndIf
                    EndIf
                  EndIf
                ElseIf HasData = #False And *wc\dwTag = #Wave_Chunk_Data
                  HasData = #True
                  *wdc = *wc
                EndIf
                
                ;lit le chunk suivant
                Offset + *wc\dwSize + SizeOf(WaveChunk)
                *wc    + *wc\dwSize + SizeOf(WaveChunk)
                
                If Length - Offset < *wc\dwSize
                  Offset = Length
                EndIf
              Wend
              
              ;On ne garde que les chunk Format et Data
              If HasFormat And HasData
                WaveSize = SizeOf(WaveFileHeader) + SizeOf(WaveFormatChunk)
                WaveSize + SizeOf(WaveDataChunk)  + *wdc\dwSize
                *wf = AllocateMemory(WaveSize)
                
                If *wf
                  ;Remplit la zone de mémoire allouée
                  *wf\dwRiff = #Wave_Chunk_Riff
                  *wf\dwSize = WaveSize - OffsetOf(WaveFileHeader\dwWave)
                  *wf\dwWave = #Wave_Chunk_Wave
                  CopyMemory( *wfc, *wf+SizeOf(WaveFileHeader),  SizeOf(WaveFormatChunk) )
                  CopyMemory( *wdc, *wf+SizeOf(WaveFileHeader)+SizeOf(WaveFormatChunk), *wdc\dwSize+SizeOf(WaveChunk) )
                  
                  ;Copie le chunk Format
                  CopyMemory( *wfc+SizeOf(WaveChunk), wfx, SizeOf(WaveFormatChunk)-SizeOf(WaveChunk) )
                  
                  dsbd\dwFlags       = #DSBCaps_LocSoftware|#DSBCaps_CtrlFrequency|#DSBCaps_CtrlPan|#DSBCaps_CtrlVolume
                  dsbd\dwBufferBytes = *wdc\dwSize
                  dsbd\lpwfxFormat   =  wfx
                  
                  If ids8\CreateSoundBuffer(dsbd, @tidsb, #Null) = #DS_OK
        Debug "oké"
                    tidsb\QueryInterface(?IID_DirectSoundBuffer8, @idsb8)
                    tidsb\Release()
                    If idsb8
                      If idsb8\Lock(#Null, #Null, @lpWrite, @dwLength, #Null, #Null, #DSBLock_EntireBuffer) = #DS_OK
                        CopyMemory(*wf+SizeOf(WaveFile), lpWrite, dwLength)
                        idsb8\UnLock(lpWrite, dwLength, #Null, #Null)
                        *dsw = AllocateMemory( SizeOf(DirectSoundWave) )
                        If *dsw
                          CopyMemory( *wf, *dsw, SizeOf(WaveFile) )
                          *dsw\lpDataSection = lpWrite
                          *dsw\Sound         = idsb8
                          *dsw\PrimaryBuffer = idsb
                          *dsw\DirectSound8  = ids8
                          Catch = *dsw
                        Else
                          idsb\Release()
                          ids8\Release()
                          idsb8\Release()
                        EndIf
                      EndIf
                    Else
                      idsb\Release()
                      ids8\Release()
                    EndIf
                  Else
                    idsb\Release()
                    ids8\Release()
                  EndIf
                EndIf
              EndIf
              
            EndIf
          EndIf
        EndIf
        
      EndIf
    EndIf
  EndIf
  ProcedureReturn Catch
EndProcedure

Procedure.l IsWave(*dsw.DirectSoundWave)
  Protected IsWave.l
  If InitWave()
    If *dsw
      If *dsw\dwRiff = #Wave_Chunk_Riff And *dsw\dwWave = #Wave_Chunk_Wave 
        If *dsw\dwFormat = #Wave_Chunk_Format And *dsw\dwData = #Wave_Chunk_Data
          IsWave = #True
        EndIf
      EndIf
    EndIf
  EndIf
  ProcedureReturn IsWave
EndProcedure

Procedure.l LoadWave(WindowID.l, Location.s)
  Protected Load.l, File.l, *ptr.l
  File = ReadFile(#PB_Any, Location)
  If File And Lof() > SizeOf(WaveFile)
    *ptr = AllocateMemory( Lof() )
    If *ptr
      ReadData( *ptr, Lof() )
      Load = CatchWave( WindowID.l, *ptr, Lof() )
      FreeMemory(*ptr)
    EndIf
    CloseFile(File)
  EndIf
  ProcedureReturn Load
EndProcedure

Procedure.l SaveWave(*dsw.DirectSoundWave, Location.s)
  Protected Save.l, File.l
  If InitWave() And IsWave(*dsw)
    File = CreateFile(#PB_Any, Location)
    If File
      Save = #True
      WriteData( *dsw, SizeOf(WaveFile) )
      WriteData(*dsw\lpDataSection, *dsw\dwDataSize)
      CloseFile(File)
    EndIf
  EndIf
  ProcedureReturn Save
EndProcedure

Procedure.l FreeWave(*dsw.DirectSoundWave)
  Protected Free.l
  If InitWave() And IsWave(*dsw)
    ;*dsw\Sound\Release()
    ;*dsw\PrimaryBuffer\Release()
    ;*dsw\DirectSound8\Release()
    Free = FreeMemory(*dsw)
  EndIf
  ProcedureReturn Free
EndProcedure

Procedure.l CloneWave(WindowID.l, *dsw.DirectSoundWave)
  Protected Clone.l, *wf.WaveFile, Length.l
  If InitWave() And IsWave(*dsw)
    Length = *dsw\dwSize+OffsetOf(WaveFile\dwWave)
    *wf = AllocateMemory(Length)
    If *wf
      CopyMemory( *dsw, *wf, SizeOf(WaveFile) )
      CopyMemory(*dsw\lpDataSection, *wf+SizeOf(WaveFile), *dsw\dwDataSize)
      Clone = CatchWave(WindowID, *wf, Length)
      FreeMemory(*wf)
    EndIf
  EndIf
  ProcedureReturn Clone
EndProcedure

Procedure.l CreateWave(WindowID.l, Depth.l, Frequency.l, Samples.l, Channels.l)
  Protected *wf.WaveFile, *dsw.DirectSoundWave
  Protected BytesPerSample.l, BlockAlign.l, Size.l
  If InitWave()
    BytesPerSample = Depth >> 3
    If BytesPerSample >= 1 And BytesPerSample <= 4
      If Frequency >= #Wave_Frequency_Min And Frequency <= #Wave_Frequency_Max
        If Channels = #Wave_Channels_Mono Or Channels = #Wave_Channels_Stereo
          If Samples >= 0
            BlockAlign = BytesPerSample * Channels
            Size = SizeOf(WaveFile) + BlockAlign * Samples
            *wf = AllocateMemory(Size)
            If *wf
              *wf\dwRiff = #Wave_Chunk_Riff
              *wf\dwSize = Size - SizeOf(WaveChunk)
              *wf\dwWave = #Wave_Chunk_Wave
  
              *wf\dwFormat         = #Wave_Chunk_Format
              *wf\dwFormatSize     = SizeOf(WaveFormatChunk) - SizeOf(WaveChunk)
              *wf\wFormatTag       = #WAVE_FORMAT_PCM
              *wf\wChannels        = Channels
              *wf\dwSamplesPerSec  = Frequency
              *wf\dwAvgBytesPerSec = Frequency * BlockAlign
              *wf\wBlockAlign      = BlockAlign
              *wf\wBitsPerSample   = Depth
  
              *wf\dwData     = #Wave_Chunk_Data
              *wf\dwDataSize = BlockAlign * Samples
              
              *dsw = CatchWave(WindowID, *wf, Size)
              FreeMemory(*wf)
            EndIf
          EndIf
        EndIf
      EndIf
    EndIf
  EndIf
  ProcedureReturn *dsw
EndProcedure

Procedure.l WaveChannels(*dsw.DirectSoundWave)
  Protected Channels.l
  If InitWave() And IsWave(*dsw)
    Channels = *dsw\wChannels
  EndIf
  ProcedureReturn Channels
EndProcedure

Procedure.l WaveFrequency(*dsw.DirectSoundWave)
  Protected Frequency.l
  If InitWave() And IsWave(*dsw)
    Frequency = *dsw\dwSamplesPerSec
  EndIf
  ProcedureReturn Frequency
EndProcedure

Procedure.l WaveDepth(*dsw.DirectSoundWave)
  Protected Frequency.l
  If InitWave() And IsWave(*dsw)
    Frequency = *dsw\wBitsPerSample
  EndIf
  ProcedureReturn Frequency
EndProcedure

Procedure.l WaveSamples(*dsw.DirectSoundWave)
  Protected Samples.l
  If InitWave() And IsWave(*dsw)
    Samples = *dsw\dwDataSize / *dsw\wBlockAlign
  EndIf
  ProcedureReturn Samples
EndProcedure

Procedure.l WaveLength(*dsw.DirectSoundWave)
  Protected Length.l
  If InitWave() And IsWave(*dsw)
    Length = (1000 * *dsw\dwDataSize) / (*dsw\wBlockAlign * *dsw\dwSamplesPerSec)
  EndIf
  ProcedureReturn Length
EndProcedure

Procedure.l WaveSaturation(*dsw.DirectSoundWave)
  Protected Saturation.l, BytesPerSample.l, i.l
  If InitWave() And IsWave(*dsw)
    i = 0
    BytesPerSample = *dsw\wBitsPerSample >> 3
    While i < BytesPerSample
      Saturation + $FF << (i << 3)
      i + 1
    Wend
    SHR Saturation, 1
  EndIf
  ProcedureReturn Saturation
EndProcedure

Procedure.l WaveSamplingRate(*dsw.DirectSoundWave)
  Protected Rate.l
  If InitWave() And IsWave(*dsw)
    Rate = *dsw\dwAvgBytesPerSec
  EndIf
  ProcedureReturn Rate
EndProcedure

Procedure.l WaveSample(*dsw.DirectSoundWave, Position.l, Mode.l)
  Protected Sample.l, Left.l, Right.l, Saturation.l, BytesPerSample.l, *ptr.l, i.l
  If InitWave() And IsWave(*dsw) And Position >= 0 And Position < WaveSamples(*dsw)
    BytesPerSample = *dsw\wBitsPerSample >> 3
    *ptr = *dsw\lpDataSection + Position * *dsw\wBlockAlign
    If *dsw\wChannels = #Wave_Channels_Mono
      While i < BytesPerSample
        Sample + PeekB(*ptr + i) << (i << 3)
        i + 1
      Wend
    Else
      While i < BytesPerSample
        Left  + PeekB(*ptr + i) << (i << 3)
        Right + PeekB(*ptr + i + BytesPerSample) << (i << 3)
        i + 1
      Wend
      
      If     Mode & #Wave_Sample_Left
        Right = Left
      ElseIf Mode & #Wave_Sample_Right
        Left  = Right
      EndIf
      
      Sample = (Right + Left) >> 1
    EndIf
    If *dsw\wBitsPerSample = 8
      If Sample < 0
        Sample + 256
      EndIf
      Sample - 127
    EndIf
    If Mode & #Wave_Sample_Percent
      Sample * 100.0 / WaveSaturation(*dsw)
    EndIf
  EndIf
  ProcedureReturn Sample
EndProcedure

Procedure.l WaveSamplePos(*dsw.DirectSoundWave, Time.l)
  Protected SamplePos.l, Length.l, fTime.f
  Length = WaveLength(*dsw)
  If InitWave() And IsWave(*dsw) And Time >=0 And Time < Length
    fTime = Time
    SamplePos = (WaveSamples(*dsw) * fTime) / Length
  EndIf
  ProcedureReturn SamplePos
EndProcedure

Procedure.l SetWavePosition(*dsw.DirectSoundWave, Position)
  Protected Set.l
  If InitWave() And IsWave(*dsw)
    If Position >= 0 And Position <= WaveSamples(*dsw)
      *dsw\Sound\SetCurrentPosition(Position)
    EndIf
  EndIf
  ProcedureReturn Set
EndProcedure

Procedure.l PlayWave(*dsw.DirectSoundWave, Looping.l)
  Protected Play.l
  If InitWave() And IsWave(*dsw)
    If Looping
      Looping = #DSBPlay_Looping
    EndIf
    SetWavePosition(*dsw, 0)
    *dsw\Sound\Play(#NULL, #NULL, #NULL)
    Play = #TRUE
  EndIf
  ProcedureReturn Play
EndProcedure

Procedure.l StopWave(*dsw.DirectSoundWave)
  Protected Stop.l
  If InitWave() And IsWave(*dsw)
    Stop = *dsw\Sound\Stop()
    SetWavePosition(*dsw, 0)
  EndIf
  ProcedureReturn Stop
EndProcedure

Procedure.l ReverseWave(*dsw.DirectSoundWave)
  Protected Reverse.l, MemStart.l, MemEnd.l, Position.l, Size.l
  If InitWave() And IsWave(*dsw)
    Size = *dsw\wBlockAlign
    MemStart = *dsw\lpDataSection
    MemEnd   = MemStart + *dsw\dwDataSize - Size
    Position = (WaveSamples(*dsw) >> 1) * Size
    
    While Position >= 0
      Swap(MemStart+Position, MemEnd-Position, Size)
      Position - Size
    Wend
    
    Reverse = #TRUE
  EndIf
  ProcedureReturn Reverse
EndProcedure

Procedure.l ConvertWaveDepth(WindowID.l, *dsw.DirectSoundWave, Depth.l)
  Protected *convert.DirectSoundWave, Ratio.f, BytesPerSample.l
  Protected i.l, Sample.l, Samples.l, *p1.l, *p2.l, Mask.l
  If InitWave() And IsWave(*dsw) And *dsw\wBitsPerSample <> Depth
    If Depth > *dsw\wBitsPerSample
      Mask  = (1 << (Depth - *dsw\wBitsPerSample))
      Ratio = Mask + 0.0
    Else
      Mask  = (1 << (*dsw\wBitsPerSample - Depth))
      Ratio = 1.0 / Mask
    EndIf
    Depth >> 3
    BytesPerSample = *dsw\wBitsPerSample >> 3
    If Depth >= 1 And Depth <= 4
      
      *convert = CreateWave(WindowID, Depth << 3, *dsw\dwSamplesPerSec, WaveSamples(*dsw), *dsw\wChannels)
      
      If *convert
        
        ;nombre d'échantillon à traiter
        Samples = *dsw\dwDataSize / BytesPerSample
        
        *p1 = *dsw\lpDataSection
        *p2 = *convert\lpDataSection
        
        While Samples > 0
          ;lecture du sample
          i = 0
          Sample = 0
          While i < BytesPerSample
            Sample + PeekB(*p1+i) << (i << 3)
            i + 1
          Wend
          *p1 + BytesPerSample
          
          ;conversion du sample
          If BytesPerSample = 1 ;le 8bits est non signé
            If Sample < 0
              Sample + 256
            EndIf
            Sample - 127
          EndIf
          Sample * Ratio
          If Depth = 1 ;le 8bits est non signé
            If Sample > 127
              Sample = 127
            EndIf
            Sample + 127
          EndIf
          
          ;écriture du nouveau sample
          i = 0
          While i < Depth
            i << 3
            Mask = $FF << i
            Mask = (Mask & Sample) >> i
            i >> 3
            PokeB(*p2 + i, Mask)
            i + 1
          Wend
          *p2 + Depth
          
          Samples - 1
        Wend
        
      EndIf
      
    EndIf
  EndIf
  ProcedureReturn *convert
EndProcedure
Dri :D
Dernière modification par Dr. Dri le sam. 10/sept./2005 22:44, modifié 10 fois.
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Message par ZapMan »

Beau travail ! C'est drôlement propre !
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Corrections :
Certains fichiers ne contenaient pas les valeurs calculées. Je les recalcule au chargement.
La fonction WaveSamplePos pouvait renvoyer une valeur incorrecte avec des paramètres corrects.
La fonction PlayWave ne prenait pas en compte si on pointait vers un Wave ou pas.

Ajouts :
ReverseWave inverse le sens de lecture d'un Wave.
L'oscilloscope inclut maintenant la possiblité de jouer un son à l'envers et une barre de progression a été ajoutée.

Dri ^^
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Corrections:
La saturation pour une résolution donnée (8bits, 16bits...) est calculée. Cela permet désormais de traiter le 24 bits.

Ajouts:
La fonction WaveSaturation()
CreateWave() crée un fichier Wave vide (sans aucun son)
ConvertWave() permet de changer la résolution d'un Wave. Fonctionne en 24 et 32 bits. Diminuer le nombre de Bits entraîne une trop grande perte de qualité
MixWaves() Permet de mélanger deux sons à conditions qu'ils aient les mêmes caractéristiques.

Dri :D
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Arf...SuperGénial !
J'adore la lecture inversée de ton scope...

Ca promet un chouette prog...

@+Jacobus
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Je reprends le développement de mes fonctions à zéro ^^
Je vais maintenant me baser sur DirectSound et plus l'api win32. Ce qui signifie à court terme que c'est plus dur à mettre en place mais qu'à long terme je pourrais proposer plus de fonctions...

@Jacobus
Merci pour le scope ^^
c'est juste un exemple d'utilisation des fonctions mais content qu'il te plaise. Avec DirectX je devrais même pouvoir changer la ProgressBar en TrackBar ;)

Dri ^^
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Le code a été mis à jour avec DirectX. Toutes les fonctions ne sont pas présentes mais il y en a une nouvelle qui constitue le noyeau dur du code. C'est CatchWave() qui au passage permet désormais d'utiliser IncludeBinary.

Les inconvénients maintenant:
Pour utiliser ces fonctions on a besoin de DirectX 8 et pour charger un simple son, on a besoin d'un WindowID.

Je rencontre aussi des problèmes plus de l'ordre du bug mais avec un code qui se complique c'est pas étonant...

En rajustant deux trois bouts de code dans le scope (comme par exemple le WindowID) ca fonctionne nickel mais je l'ai pas mis à jour dans le zip...

Dri
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

DirectX pose un problème que PlaySound_() gère très bien... Il refuse de dépasser le 16bits donc je me retrouve bloqué avec du 8/16bits. Si quelqu'un sait comment gérer du 24/32bits (et même plus) avec DirectSound8 je suis preneur...

En attendant il refuse de me créer un buffer pour autre chose que du 8/16bits et ma fonction de convertion de la résolution du son tombe à l'eau... Si jamais je dois repasser à win32 je serais un peu dégoûté mais au moins ca fonctionnera... Mais on pourra jouer un seul Wave à la fois...

Dri :mad:
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

:? Pas cool tout ca !
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Je viens de trouver ceci en me ballandant sur le msdn... C'est le comportement de DirectX vis-à-vis du son... DirectSound et DirectShow semble-t-il...
This filter supports a range of sample rates that depends on the audio driver.
En gros je voudrais que ceux qui ont 5 minutes tentent de convertir un son wav quelconque en wave de 32bits... J'aimerais aussi connaître la config de ceux chez qui ca fonctionne...

Code : Tout sélectionner

IncludeFile "pcm.pb" ;ca c'est le code source d'au-dessus
OpenWindow(0,0,0,0,0,0,"") ;ca c'est la magie DirectX

Fichier$ = OpenFileRequester("Wav", "", "Fichiers Wave|*.wav", 0)
Son = LoadWave(WindowID(), Fichier$)

Debug ConvertWaveDepth(WindowID(), Son, 32)
;si c'est différent de 0 c'est bon
Dri
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

J'ai un pb avec la fct CreateWave() :
Elle n'est pas présente dans ta source !!! :?

De plus tu à oublié de modifier un 'Declare' : Declare.l ConvertWaveDepth(WindowID.l, *dsw.DirectSoundWave, Depth)
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

j'ajoute ca tout de suite

Dri
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Y a encore des erreurs :
* mm mauvaise déclaration que mon post précédent :wink:
* CreateWave() , faut supprimer Window dans les paramètre (dans la fct ConvertWaveDepth()

Mais après correction, je trouve ca :
Error at line 645 : Specified adress is null
Ligne correspondante : PokeB(*p2 + i, Mask)

Donc tjrs pas de valeur pr cette fois :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

bon je ferais un exemple moi-même et je mettrai comlpètement à jour le code après avoir testé. Parce que là je n'ai fait qu'ajouter les bouts de code manquants...

Dri

PS. désolé :oops:
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Message par Patrick88 »

j'ai une errerur :

ligne 483 - 'saturation is not a valid operator'


pat
Répondre