[PureWave] Player Wav avec sa WavForm

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

[PureWave] Player Wav avec sa WavForm

Message par GallyHC »

Bonjour tous,

Voila une petite avancer d'un code pour afficher la forme d'un Wav et de pouvoir jouer le son tout en voyant la position dans la forme. Voila en gros ce que cela donne :

Image

Il reste pas mal de chose a faire, je verrais cela plus tard. En gros ce qui reste a faire :

- Mettre l'image de la forme du wav dans une image indépendante pour ne pas la refaire a chaque fois.

Voila le code :

Code : Tout sélectionner

; +======================================================+
; | ROUTINE DE CHARGEMENT DU FORMAT WAV (SPECTRE DU SON) |
; +------------------------------------------------------+
; | COPYRIGHT(C)2007-2012, ALL RIGHT RESERVED KOAKDESIGN |
; +--------------+---------------------------------------+
; | Program type | PUREBASIC 5.2b8                        |
; +--------------+---------------------------------------+
; | VER & REV    | 0.0.3                                 |
; +--------------+---------------------------------------+
; | Comments:    | unicode supported, realtime scroll    |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | Original Version: 0.0.2                              |
; +--------------+---------------------------------------+
; | Created by   | GallyHomeCorp                         |
; | Graphix by   | GallyHomeCorp                         |
; +--------------+---------------------------------------+
; | Comments:    |                                       |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | OS System
; +--------------+---------------------------------------+
; | Window       | Oui                                   |
; | Linux        | Oui                                   |
; | MacOS        | Oui                                   |
; +======================================================+

; ****************************************************************************
; ****************************************************************************

EnableExplicit

; ****************************************************************************
; ****************************************************************************

Declare.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
Declare.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
Declare ScrollWAVImage()

; ****************************************************************************
; ****************************************************************************

Structure WaveFileHeader
   chunkid.a[4]
   chunksize.l
   format.a[4]
   fmtchunkid.a[4]
   fmtchunksize.l
   audioformat.u
   numchannels.u
   samplerate.l
   byterate.l
   blockalign.u
   bitspersample.u
   CompilerIf #PB_Compiler_Unicode = 1
      bitformatextra.u
   CompilerEndIf
   datachunkid.a[4]
   datachunksize.l
EndStructure

Global sFileName.s
Global Dim tabWaveLenA.a(1)
Global Dim tabWaveLenB.w(1)
Global tabWaveFile.WaveFileHeader

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Macro ReadWavString(structProperty)
   LSet(PeekS(@structProperty, 4, #PB_Ascii), 4, " ")
EndMacro
Macro WriteWavString(structProperty, value)
   PokeS(@structProperty, value, 4, #PB_Ascii)
EndMacro 

Procedure.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
   ; ROUTINE DE CHARGEMENT DU HEADER DU WAV.
   Protected i
   Protected file
   Protected flen
   Protected dlen
   Protected load.b = #False
   Protected lDataChunk
   Protected datachunkid.s{4}
   
   file = ReadFile(#PB_Any, filename)
   If file <> 0
      sFileName = filename
      flen = Lof(file)
      ReadData(file, tabWaveFile, SizeOf(WaveFileHeader))
      If ReadWavString(tabWaveFile\datachunkid) <> "data"
         For i = 0 To 2048 Step 2
            FileSeek(file, (SizeOf(WaveFileHeader)- 6)+ i)
            ReadData(file, @datachunkid, 4)
            If datachunkid = "data"
               lDataChunk = i + 2
               WriteWavString(tabWaveFile\datachunkid, "data")
               tabWaveFile\datachunksize = ReadLong(file)
               Break
            EndIf
         Next i
      EndIf
      ReDim tabWaveLenA(1)
      ReDim tabWaveLenB(1)
      If ReadWavString(tabWaveFile\chunkid) = "RIFF" And
         ReadWavString(tabWaveFile\format) = "WAVE" And
         ReadWavString(tabWaveFile\fmtchunkid) = "fmt " And
         ReadWavString(tabWaveFile\datachunkid) = "data" And tabWaveFile\DataChunkSize > 44
         dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
         Select tabWaveFile\BitsPerSample
            Case 8
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenA(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenA(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenA(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
            Case 16
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenB(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenB(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenB(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
         EndSelect
      EndIf
      CloseFile(file)
   EndIf
   ProcedureReturn #True
   
EndProcedure

Procedure.s GetWAVTime()
   ; ROUTINE DE RECUPERATION DU TEMPS DU WAV.
   ProcedureReturn FormatDate("%hh:%ii:%ss", Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest))
   
EndProcedure

Procedure.l ParseWavTime(date.s, val)
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   If val < 1
      val = 1
   EndIf
   If val > 3
      val = 3
   EndIf
   ProcedureReturn Val(StringField(date, val, ":"))
   
EndProcedure

Procedure GetWavInformation()
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   Protected stemp.s
   stemp = "ChunkID : " + tabWaveFile\chunkid +
           #CRLF$ + "ChunkSize : " + Str(tabWaveFile\ChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + ReadWavString(tabWaveFile\Format) +
           #CRLF$ + "fmtChunkID : " + ReadWavString(tabWaveFile\fmtChunkID) +
           #CRLF$ + "FmtChunkSize : " + Str(tabWaveFile\FmtChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + Str(tabWaveFile\AudioFormat)+
           #CRLF$ + "Channels : " + Str(tabWaveFile\NumChannels)+
           #CRLF$ + "SampleRate : " + Str(tabWaveFile\SampleRate)+ " Hz" +
           #CRLF$ + "BitsRate : " + Str(tabWaveFile\ByteRate)+
           #CRLF$ + "BlockAlign : " + Str(tabWaveFile\BlockAlign)+
           #CRLF$ + "BitsPerSample : " + Str(tabWaveFile\BitsPerSample)+
           #CRLF$ + "DataChunkID : " + ReadWavString(tabWaveFile\DataChunkID) +
           #CRLF$ + "DataChunkSize : " + Str(tabWaveFile\DataChunkSize)+ " Octets" +
           #CRLF$ + #CRLF$ + "Temps Total : " + GetWAVTime()
   MessageRequester("PureWav", stemp, #PB_MessageRequester_Ok)
   
EndProcedure

Procedure.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
   ; ROUTINE DE TRACAGE DU SPECTRE DU WAV.
   Protected i
   Protected j
   Protected dlen
   Protected lpas
   Protected ysav
   Protected zsav
   Protected lpos
   Protected fpos.f
   Protected time.s = GetWAVTime()
   Protected lsec.f = w / ((ParseWavTime(time, 1) * 3600) + (ParseWavTime(time, 2) * 60) + ParseWavTime(time, 3))
   
   If z < 1
     z = 1
     ProcedureReturn #False
   EndIf
   If z > 16
      z = 16
     ProcedureReturn #False
   EndIf
   If ReadWavString(tabWaveFile\chunkid)<> "RIFF" Or
      ReadWavString(tabWaveFile\format)<> "WAVE" Or
      ReadWavString(tabWaveFile\fmtchunkid) <> "fmt " Or
      ReadWavString(tabWaveFile\datachunkid) <> "data"
      ProcedureReturn #False
   EndIf
   If tabWaveFile\DataChunkSize < 1
      ProcedureReturn #False
   EndIf
   
   ;
   ; (Test) Moving real play
   ;
  If play
    i    = GetSoundPosition(0, #PB_Sound_Frame)
    j    = SoundLength (0, #PB_Sound_Frame)
    fpos = w / j
    If fpos * (i * z) - p => w / 2 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > 1 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > GetGadgetState(1)
      SetGadgetState(1, GetGadgetState(1) + 1)
      ScrollWAVImage()
      ProcedureReturn #False
    EndIf
  EndIf
   ;
   ; (Test) Moving real play
   ;
   
   
   If StartDrawing(CanvasOutput(0))
      Box(0, 0, w, h, $FFFFFF)
      dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
      Select tabWaveFile\NumChannels
         Case 1
            lpas =(dlen / w)/ z
            lpos =((dlen / lpas)- w)
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h -(h / 6), w, h -(h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenA(((i + p) * lpas) + j) - 128), $e8a200 + ((i * 255) / w))
                           ysav =(tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
               Case 16
                  ysav = tabWaveLenB(0)/(h / 1.5)
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h - (h / 6), w, h - (h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 -(z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)), $e8a200 + ((i * 255)/ w))
                           ysav = tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
            EndSelect
         Case 2
            lpas = ((dlen / w) * 2) / z
            lpos = ((dlen / lpas)* 2) - w
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(1)- 128
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h - (h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenA(((i + p) * lpas) + j + 1) - 128), $e8a200 + ((i * 255) / w))
                           ysav = (tabWaveLenA(((i + p) * lpas) + j + 1) - 128)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenA(((i + p) * lpas) + j)- 128), $e8a200 + ((i * 255) / w))
                           zsav = (tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255)/ w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255)/ w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
               Case 16
                  ysav = tabWaveLenB(1)/(h / 0.9)
                  zsav = tabWaveLenB(0)/(h / 0.9)
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h -(h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenB(((i + p) * lpas) + j + 1) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           ysav = tabWaveLenB(((i + p)* lpas) + j + 1)/(h / 0.6)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           zsav = tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255) / w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255) / w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
            EndSelect
      EndSelect
      If play
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box((fpos * (i * z)) - p - 2, 0, 4, h, RGBA(200, 0, 0, 100))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(6, 1, FormatDate("%hh:%ii:%ss", GetSoundPosition(0, #PB_Sound_Millisecond)  / 1000), $000000)
      EndIf
      j = 0
      DrawingMode(#PB_2DDrawing_Transparent)
      If Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest)> 1
         For i = 1 To(w * z)
            j + 1
            i + (lsec * 30) * z
            If i - p => 0 And i - p <= w
               LineXY(i - p, 0, i - p, h, $0000AA)
               DrawText((i - p)- 60, h - 15, FormatDate("%hh:%ii:%ss", (j * 30)), $0000AA)
            EndIf
         Next i
      EndIf
      DrawText(w - 60, 1, time, $000000)
      StopDrawing()
      If z = 1
         SetGadgetState(1, 0)
      EndIf
      SetGadgetAttribute(1, #PB_ScrollBar_Maximum, lpos)
      ProcedureReturn #True
   EndIf
   
   
EndProcedure

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

If Not InitSound()
   MessageRequester("Initialize the sound environment", "No sound supported!")
   End
EndIf

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Global zoom.l = 1
Global pos.l = 0
Global play.b = #False

Procedure ScrollWAVImage()
   pos = GetGadgetState(1)
   DrawWAVFile(0, 0, 800, 256, zoom, pos, play)
 EndProcedure
 
Procedure ZoomWAVImage()
   Select EventGadget()
      Case 5
         zoom - 1
         If zoom < 2
            pos = 0
         EndIf
         If zoom < 1
            zoom = 1
         EndIf
      Case 6
         zoom + 1
         If zoom > 16
            zoom = 16
         EndIf
   EndSelect
   DrawWAVFile(0, 0, 800, 256, zoom, pos)
EndProcedure
Procedure LoadAndPlayWAVSound()
   Select EventGadget()
      Case 2
         OpenWAVFile(OpenFileRequester("Ouvrir un archive Wav", "", "Musique Wav|*.wav", 0), 0, 0, 800, 256, zoom)
         GetWavInformation()
       Case 3
         If sFileName <> #NULL$
           If LoadSound(0, sFileName)
              PlaySound(0)
           EndIf
         EndIf
      Case 4
         If IsSound(0)
            StopSound(0)
         EndIf
   EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 800, 400, "PureWave", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
   CanvasGadget(0, 0, 0, 800, 256, 0)
   ScrollBarGadget(1, 0, 257, 800, 18, 1, 1, 1000)
   ButtonGadget(2, 10, 300, 100, 32, "Fichier Wav")
   ButtonGadget(3, 120, 300, 100, 32, "Play")
   ButtonGadget(4, 230, 300, 100, 32, "Stop")
   ButtonGadget(5, 10, 340, 100, 32, "Zoom -")
   ButtonGadget(6, 120, 340, 100, 32, "Zoom +")
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(2, @LoadAndPlayWAVSound())
   BindGadgetEvent(3, @LoadAndPlayWAVSound())
   BindGadgetEvent(4, @LoadAndPlayWAVSound())
   BindGadgetEvent(5, @ZoomWAVImage())
   BindGadgetEvent(6, @ZoomWAVImage())
   Repeat      
      play = Bool(IsSound(0) And SoundStatus(0)=#PB_Sound_Playing)
      DrawWAVFile(0, 0, 800, 256, zoom, pos, play)      
   Until WaitWindowEvent(1)= #PB_Event_CloseWindow
EndIf
Voila en espérant que cela soit utile?

Cordialement,
GallyHC
Dernière modification par GallyHC le lun. 12/août/2013 14:34, modifié 8 fois.
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
MLD
Messages : 1103
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: [PureWave] Player Wav avec sa WavForm

Message par MLD »

Bonjour Gally

Super travail.
Pour le bug je n'est pas le temp en ce moment, et moi aussi j'ai mon lot de bugs depuis la 5.11. J'éssais de contourner ceux rencontrés par mes programmes, ce qui me prend beaucoup de travail.
Avatar de l’utilisateur
Ar-S
Messages : 9476
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [PureWave] Player Wav avec sa WavForm

Message par Ar-S »

C'est joli ! En tout cas pour ce genre d'édition de son en graph j'utilise SoundForge pour faire des montages audio. Il existe aussi Audacity qui lui est gratos. Tout ça pour dire que je regarde tes avancées par curiosité mais je doute que ça me serve.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Fred
Site Admin
Messages : 2651
Inscription : mer. 21/janv./2004 11:03

Re: [PureWave] Player Wav avec sa WavForm

Message par Fred »

GallyHC a écrit :Par contre, je rencontre un Bug avec la constante "#PB_Sound_Millisecond" avec la commande "GetSoundPosition()". A un moment elle boucle a "0" même si le son est toujours en train d'être jouer, mais je ne vais pas remonté l'infos a Fred alors si quelqu'un a le courage.
Ce bug a été reporté sur le forum anglais et corrigé pour la prochaine version.
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [PureWave] Player Wav avec sa WavForm

Message par GallyHC »

Bonjour,

Fred> Merci alors...

Ar-S> En fait c'été un code que j'avais commencer et je me suis dit que serait sympa de continuer. Perso je penses que je l'utiliserais pour mon programme de Contrôleur DMX ;) (mais peu être pas pour les premières version.

MDL> Merci.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [PureWave] Player Wav avec sa WavForm

Message par blendman »

beau travail, bravo :)

Avec un truc comme ça, tu pourrais faire une sorte de logiciel multi-pistes ou on peut changer la tonalité et la vitesse de la wave et ensuite mixer tout ça, non ?
Ce serait un gros boulot, c'est sûr ^^.
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [PureWave] Player Wav avec sa WavForm

Message par graph100 »

Son code affiche le wav, mais la lecture est effectuée par l'intermédiaire de PureBasic.
Il ne peut donc pas manipuler le son et l'écouter en direct, ou alors il faudrait réenregistrer le fichier wav.

(j'attends justement la partie qui permet de créer un son, et de le jouer en direct de la création, sans interruption)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [PureWave] Player Wav avec sa WavForm

Message par blendman »

graph100 a écrit :Il ne peut donc pas manipuler le son et l'écouter en direct, ou alors il faudrait réenregistrer le fichier wav.
Yep. Mais il peut tout de même faire du mixage (avec #PB_Sound_MultiChannel par exemple), régler le volume.

Comme je disais, on peut "facilement" réaliser un petit logiciel de mixage de sample (un peu comme la versionfree d'acid xpress mais en beaucoup plus simple):
- on crée des pistes dans lequel on peut régler le son, et son volume (avec des courbes pour les fades in/out)
- avec SetSoundFrequency(#Son, Frequence [, Canal]) on peut régler la fréquence du son, n'est-ce pas la tonalité ?

Genre ceci :
(vieille version de acidxpress)
Image

version récente d'acidxpress :
Image
Image

Ce qui manque c'est une fonction qui permettrait d'enregistrer le son obtenu avec tous les samples qui se jouent et le mixage final.
Un truc genre savesound() ou recordsound() :)
(j'attends justement la partie qui permet de créer un son, et de le jouer en direct de la création, sans interruption)
il m'a semblé voir un code qui permettait ça sur le forum anglais.
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [PureWave] Player Wav avec sa WavForm

Message par GallyHC »

:) Ouep pourquoi pas, mais perso j'avais juste besoin d'avoir la forme du son (j'essaierais aussi de faire pour les MP3). Et cela irait bien avec mes sliders....

Image

Enfin ce n'est pas mon but pour le moment

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [PureWave] Player Wav avec sa WavForm

Message par graph100 »

Oui, j'avais cherché des codes la-dessus.
Mais je ne les ai pas encore exploité, un gros manque de temps...

Code : Tout sélectionner

;Raw Sound Creation Demo
;By: Joakim L. Christiansen
;Version: 1.1

EnableExplicit

; Structure WAVEFORMATEX ;may need to uncomment on Linux or Mac
;   wFormatTag.w
;   nChannels.w
;   nSamplesPerSec.l
;   nAvgBytesPerSec.l
;   nBlockAlign.w
;   wBitsPerSample.w
;   cbSize.w
; EndStructure

Global format.WAVEFORMATEX

Procedure setWaveFormat(bitsPerSample=16,samplesPerSec=44100)
	format\wFormatTag = #WAVE_FORMAT_PCM
	format\nChannels = 1 ;mono
	format\wBitsPerSample = bitsPerSample ;8/16
	format\nSamplesPerSec =  samplesPerSec ;8000 Hz, 11025 Hz, 22050 Hz, and 44100 Hz
	format\nBlockAlign = (format\nChannels * format\wBitsPerSample) / 8 ;equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte).
	format\nAvgBytesPerSec = format\nSamplesPerSec * format\nBlockAlign ;equal to the product of nSamplesPerSec and nBlockAlign
EndProcedure

Procedure.l createTone(*address,volume.d,duration,frequency.d) ;returns needed size if address=0
	;creates a triangle wave
	Protected sample.l, result
	Protected pos, dir, waveY.d, maxValue, centerValue
	Protected samplesPerHalfWave, waveIncrementValue.d, size
	Protected samplesSinceHalfWave, waveTop.d
	
	size = (format\nSamplesPerSec / 1000*duration) * format\wBitsPerSample / 8
	If *address = 0 ;return size needed
		ProcedureReturn size
	EndIf
	
	If format\wBitsPerSample = 8
		maxValue = 255
	ElseIf format\wBitsPerSample = 16
		maxValue = 65535
	EndIf
	centerValue = (maxValue/2)
	
	waveTop = volume/1000 * centerValue
	samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
	waveIncrementValue = waveTop / samplesPerHalfWave
	
	For pos=0 To size
		If dir=0
			waveY + waveIncrementValue
		Else
			waveY - waveIncrementValue
		EndIf
		samplesSinceHalfWave + 1
		If samplesSinceHalfWave >= samplesPerHalfWave
			dir = dir!1 ;switch it
			samplesSinceHalfWave = 0
		EndIf
		
		If format\wBitsPerSample = 8
			sample = centerValue + waveY
			PokeA(*address+pos,sample)
		ElseIf format\wBitsPerSample = 16
			sample = waveY
			PokeW(*address+pos,sample)
			pos+1
		EndIf
	Next
EndProcedure

Procedure.l createToneEx(*address,volumeAtStart.d,volumeAtEnd.d,duration.d,frequencyAtStart.d,frequencyAtEnd.d=0,noiseAtStart.d=0,noiseAtEnd.d=0,backToStart=0) ;returns needed size if address=0
	;creates a triangle wave with added effects
	Protected sample.l, result, pos, dir, waveY.d, maxValue, centerValue
	Protected samplesPerHalfWave.d, waveIncrementValue.d, size, samplesSinceHalfWave, waveTop.d
	Protected frequency.d, frequencyIncrementValue.d, noise.d, noiseIncrementValue.d, lastNoise.d, halfSize, loop, loops
	Protected waveYpos.d, volumeIncrementValue.d, volume.d
	volume = volumeAtStart
	frequency = frequencyAtStart
	noise = noiseAtStart
	
	size = (format\nSamplesPerSec / 1000*duration) * format\wBitsPerSample / 8
	If *address = 0 ;return size needed
		If backToStart
			ProcedureReturn size * 2
		Else
			ProcedureReturn size
		EndIf
	EndIf
	
	If format\wBitsPerSample = 8
		maxValue = 255
	ElseIf format\wBitsPerSample = 16
		maxValue = 65535
	EndIf
	centerValue = (maxValue/2)
	waveTop = centerValue
	
	samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
	waveIncrementValue = waveTop / samplesPerHalfWave
	
	volumeIncrementValue = (volumeAtEnd - volumeAtStart) / size * format\wBitsPerSample/8
	frequencyIncrementValue = (frequencyAtEnd - frequencyAtStart) / size * format\wBitsPerSample/8
	noiseIncrementValue = (noiseAtEnd - noiseAtStart) / size * format\wBitsPerSample/8
	
	If backToStart: loops=1: EndIf
	For loop=0 To loops
		For pos=pos To size
			If volumeAtEnd
				volume + volumeIncrementValue
			EndIf
			If frequencyAtEnd
				frequency + frequencyIncrementValue
				samplesPerHalfWave = (format\nSamplesPerSec / frequency) / 2
				waveIncrementValue = waveTop / samplesPerHalfWave
			EndIf
			If noiseAtEnd
				noise + noiseIncrementValue
			EndIf
			
			If dir=0
				waveYpos + waveIncrementValue
			Else
				waveYpos - waveIncrementValue
			EndIf
			samplesSinceHalfWave + 1
			If samplesSinceHalfWave >= samplesPerHalfWave
				If dir=0
					waveYpos = waveTop
				Else
					waveYpos = -waveTop
				EndIf
				dir = dir!1 ;switch it
				samplesSinceHalfWave = 0
			EndIf
			
			waveY = waveYpos
			
			;waveY = waveY*16
			;waveY + Random(90000)
			
			
			If noiseAtStart
				If lastNoise >= noise; Random(noise) = 0
					Select 0
						Case 0: waveYpos = Random(maxValue)-centerValue
						Case 1: waveY = Random(maxValue)-centerValue
							;Case 2: waveYpos = Random(maxValue) ; waveY + Random(90000)
					EndSelect
					lastNoise = 1
				Else
					lastNoise+1
				EndIf
			EndIf
			
			;adjust volume
			waveY = volume/1000 * waveY
			
			If format\wBitsPerSample = 8
				sample = centerValue + waveY
				PokeA(*address+pos,sample)
			ElseIf format\wBitsPerSample = 16
				sample = waveY
				PokeW(*address+pos,sample)
				pos+1
			EndIf
		Next
		
		If backToStart ;morph back
			If volumeAtEnd
				volume    = volumeAtEnd
			EndIf
			If frequencyAtEnd
				frequency = frequencyAtEnd
			EndIf
			If noiseAtEnd
				noise     = noiseAtEnd
			EndIf
			volumeIncrementValue    = -volumeIncrementValue
			frequencyIncrementValue = -frequencyIncrementValue
			noiseIncrementValue     = -noiseIncrementValue
			size+size
		EndIf
	Next
EndProcedure

Procedure addWaveHeader(*address,dataSize,channels,samplesPerSec,blockAlign,bitsPerSample)
	; RIFF Chunk
	PokeL(*address+ 0, 'FFIR')
	PokeL(*address+ 4, dataSize + 36)
	PokeL(*address+ 8, 'EVAW')
	; FORMAT Chunk
	PokeL(*address+ 12, ' tmf')
	PokeL(*address+ 16, $0010)
	PokeW(*address+ 20, $01)
	PokeW(*address+ 22, channels)
	PokeL(*address+ 24, samplesPerSec)
	PokeL(*address+ 28, samplesPerSec * channels * (bitsPerSample / 8) )
	PokeW(*address+ 32, blockAlign)
	PokeW(*address+ 34, bitsPerSample)
	; DATA Chunk
	PokeL(*address+ 36, 'atad')
	PokeL(*address+ 40, dataSize)
EndProcedure

Procedure catchTone(volume,duration,frequency)
	Protected *memory, id, size
	size = createTone(0,volume,duration,frequency) ;get size
	*memory = AllocateMemory(44+size)
	createTone(*memory+44,volume,duration,frequency) ;write wave data to memory
	addWaveHeader(*memory,size,format\nChannels,format\nSamplesPerSec,format\nBlockAlign,format\wBitsPerSample)
	id = CatchSound(#PB_Any,*memory)
	FreeMemory(*memory)
	ProcedureReturn id
EndProcedure

Procedure catchToneEx(volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd=0,noiseAtStart=0,noiseAtEnd=0,backToStart=0)
	Protected *memory, id, size
	size = createToneEx(0,volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd,noiseAtStart,noiseAtEnd,backToStart) ;get size
	*memory = AllocateMemory(44+size)
	createToneEx(*memory+44,volumeAtStart,volumeAtEnd,duration,frequencyAtStart,frequencyAtEnd,noiseAtStart,noiseAtEnd,backToStart) ;write wave data to memory
	addWaveHeader(*memory,size,format\nChannels,format\nSamplesPerSec,format\nBlockAlign,format\wBitsPerSample)
	id = CatchSound(#PB_Any,*memory)
	FreeMemory(*memory)
	ProcedureReturn id
EndProcedure

InitSound()
setWaveFormat(16, 44100)
Define snd_explosion, snd_laser, snd_shoot, snd_pacman, snd_flying

snd_explosion = catchToneEx(1000,100,  1000,  50,20,  20,100)
snd_laser = catchToneEx(1000,100,  300,  1500,200)
snd_shoot = catchToneEx(1000,1,  500,  200,10,  1,10)
snd_pacman = catchToneEx(500,0,  100,  400,200, 0,0, #True)
snd_flying = catchToneEx(500,0,  200,  10,0, 5,10, #True)

; PlaySound(catchToneEx(1000,1000,  1000,  500, 200, 2,3)):Delay(1000)

; PlaySound(catchToneEx(1000,100,  2000,  200,40, 0,0)):Delay(2000)
; PlaySound(catchToneEx(1000,100,  2000,  10,200, 100,1 )):Delay(2000)
; PlaySound(snd_flying): Delay(400)
; PlaySound(snd_flying): Delay(400)
; PlaySound(snd_flying): Delay(400)
; PlaySound(snd_flying): Delay(400)
PlaySound(snd_pacman): Delay(200)
; PlaySound(snd_pacman): Delay(200)
; PlaySound(snd_explosion): Delay(1000)
; PlaySound(snd_laser): Delay(300)
; PlaySound(snd_laser): Delay(300)
; PlaySound(snd_shoot): Delay(1000)
; PlaySound(catchToneEx(1000,100,  2000,  200,10, 1,100 )):Delay(2000)

;Have fun! ;-)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: [PureWave] Player Wav avec sa WavForm

Message par graph100 »

Un des problèmes que j'ai rencontré se situe dans la création de sons, et de leur lecture "à la volée", on entend toujours le changement de son avec playsound().
Je ne sais pas si il possible de "timer" les lectures de façon à pouvoir ne pas entendre les changements, je n'ai pas fait pour le moment assez de test là dessus.

@GallyHC : hésite pas à me dire un truc :lol:
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [PureWave] Player Wav avec sa WavForm

Message par GallyHC »

Bonjour,

Code mis a jour (quelque modification par "eddy" du forum anglais). J'ai refait le code de play temps réel pour qu'il soit plus précis.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [PureWave] Player Wav avec sa WavForm

Message par GallyHC »

Bonjour,

En test, ajout du décalage de la "wavform" si Zoom est si le son ce joue.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: [PureWave] Player Wav avec sa WavForm

Message par venom »

Excellent, fonctionne bien chez moi.
Bravo






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: [PureWave] Player Wav avec sa WavForm

Message par GallyHC »

Bonjour,

Une petite correction dans le "Header", qui provoquer un problème avec le mode Unicode activé (En première page).

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Répondre