SoundEasy.pbi include file adds CreateSound() command

Share your advanced PureBasic knowledge/code with the community.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: SoundEasy.pbi include file adds CreateSound() command

Post by BasicallyPure »

einander wrote:Is there a way to change the sound frequency of a created sound?
Other than using SetSoundFrequency() which you already know about, I don't know how to change the frequency of a created sound.
eddy wrote:I want to load custom wave data.
For example, you can design wave data in a canvas gadget right after you test your sound.
Edit: made better code for experimentation.
I think this will help you.

Code: Select all

; for eddy
;
; Don't change the default sound parameters with SetSoundParameters() or this code will break.
; defaults are sample rate = 44100, resolution = 2 bytes (16 bit), channels = 1 (mono)
; place your experimental waveform formulas in the FillBuffer() procedure at the location indicated.

IncludeFile "SoundEasy.pbi"

flags.i = #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget
If Not OpenWindow(0, 0, 0, 800, 250, "plot audio data", flags) : End : EndIf
If Not InitSound() : End : EndIf

CanvasGadget(0, 0, 0, 800, 250)

Declare PlotBuffer(*Buffer)
Declare FillBuffer(frequency.f, amplitude)

*Buffer = InitAudioBuffer(1) ; create 1 second empty audio buffer
FillBuffer(220, 50) ; choose frequency and amplitude
PlotBuffer(*buffer)
CatchSound(0, *buffer)
PlaySound(0)

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend

End

Procedure FillBuffer(frequency.f, amplitude)
   Static PIx2.f = #PI * 2
   *buffer = InitAudioBuffer(-1)
   duration.f = InitAudioBuffer(-2)
   
   ; tweak frequency so waveform loops without glitches
   frequency = Round(frequency * duration,#PB_Round_Nearest)/duration
   
   *FirstSample = *Buffer + 44
   *LastSample = *FirstSample + PeekL(*Buffer + 40) - 1
   
   ang.f = 0 ; starting phase angle (radians)
   angStep.f = frequency / 44100 * PIx2 ; angle step size (radians)
   
   ; if waveform formulas produce values from -1 to +1 use this scale factor
   sf.f = (Pow(2,16)/2 - 1) * (amplitude / 100)
   
   For *n = *FirstSample To *LastSample Step 2 ; because each sample is 2 bytes (16 bits)
      
      ; ***** place your experimental waveform formulas here *****
      ;
      value = Sin(ang) * sf
      ;
      ; **********************************************************
      
      PokeW(*n, value)
      ang + angStep
      If ang > PIx2 : ang - PIx2  : EndIf
   Next *n
   
EndProcedure

Procedure PlotBuffer(*buffer)
   *FirstSample = *Buffer + 44 ; memory location of first audio sample
   *LastSample = *FirstSample + PeekL(*Buffer + 40) - 1 ; location of last audio sample
   
   StartDrawing(CanvasOutput(0))
      w = OutputWidth()
      h = OutputHeight()
      mid = h / 2
      Box(0,0,w,h,$0B5117)
      scale.f = (h - 1) / (Pow(2,16) - 1)
      LineXY(0, mid, w, mid, $0BF417)
      
      lastY = mid + (scale * PeekW(*FirstSample))
      
      For n = *FirstSample To *LastSample Step 2
         sampleData.w = PeekW(n)
         y = mid + (sampleData * scale)
         LineXY(lastX, lastY, x, y, $FFFFFF)
         x + 1
         lastX = x
         lastY = y
         If x > w - 1 : Break : EndIf
      Next n
   StopDrawing()
EndProcedure
Last edited by BasicallyPure on Tue Feb 26, 2013 9:10 pm, edited 5 times in total.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: SoundEasy.pbi include file adds CreateSound() command

Post by Joris »

einander wrote:Is there a way to change the sound frequency of a created sound?
...
I don't dare... or do I...
Is there also a way to change the 'sound color' of a created sounds ?

Still I'm already thankful to you guys, great stuff here.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: SoundEasy.pbi include file adds CreateSound() command

Post by BasicallyPure »

Joris wrote:Is there also a way to change the 'sound color' of a created sounds ?
Once a sound is captured with CatchSound() there is no way to change it.
You can create and tweak you sound any way you like as long as you are working in the buffer created with InitAudioBuffer.
The code I posted above for eddy is wide open for experimentation in that regard.

BP
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: SoundEasy.pbi include file adds CreateSound() command

Post by eddy »

Thanks. It's a good start. :D
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by Simo_na »

Cool.

Three things i'd like to see in SoundEasy.pbi

A bi-directional flag to sweep function ? (EG. 440 -> 880 -> 440)...(plus not-linear flag (logarithmic) )

A way to set how many times it "cycles" (sweep loop)...

The easy generation of PinkNoise...

:)
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by Simo_na »

I have a function generator (Rigol) and with this i have generated a 3.18 KHz square wave,
i've analyzed the spectrogram with Visual Analyzer and with the light version of Spectraplus,
the spectrogram is different from a square wave generated with the SoundEasy

at this point I have generated a square wave with the internal generator of Spectraplus,
which is equal to the Rigol function generator...
:D
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: SoundEasy.pbi include file adds CreateSound() command

Post by BasicallyPure »

Simo_na wrote:the spectrogram is different from a square wave generated with the SoundEasy
Make sure the sample rate is the same for all sounds when you do the comparison.
SoundEasy uses a sample rate of 44100 by default.
It can be changed by using the SetSoundParameters() procedure.
Only 5512, 11025, 22050, 44100 are allowed by SoundEasy.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by Simo_na »

BasicallyPure wrote:
Simo_na wrote:the spectrogram is different from a square wave generated with the SoundEasy
Make sure the sample rate is the same for all sounds when you do the comparison.
SoundEasy uses a sample rate of 44100 by default.
It can be changed by using the SetSoundParameters() procedure.
Only 5512, 11025, 22050, 44100 are allowed by SoundEasy.
yes is the same, for comparing i use 44100 or 88200, in this test i don't have modified nothing, in this case I left everything set on default for all device, SoundEasy included
Rigol 44100/16
SoundEasy 44100/16
Visual analyzer 44100/16
SpectraPlus 44100/16
if you see the waveform with the oscilloscope , the waveform is identical, but if you see the waveform spectrum
you will see only a certain similarity, I will try to repeat the test for certainty to have done all correctly.
gekkonier
User
User
Posts: 78
Joined: Mon Apr 23, 2007 9:42 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by gekkonier »

I know, old thread, but this rocks!
gekkonier
User
User
Posts: 78
Joined: Mon Apr 23, 2007 9:42 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by gekkonier »

Just for fun, uncomplete morse repl:

Code: Select all

InitSound()
IncludeFile "SoundEasy.pbi"
EnableExplicit

Global speed.f = 0.1
Global speedms.f = speed * 1000
Global ditsnd.i = CreateSound(#PB_Any, 1000, speed, 25, 0, #WF_SineWave, 0, 1)
Global dahsnd.i = CreateSound(#PB_Any, 1000, speed * 3, 25, 0, #WF_SineWave, 0, 1)

Global NewMap Morsecode.s()
Morsecode(" ") = " "
Morsecode("A") = ".-"
Morsecode("B") = "-..."
Morsecode("C") = "-.-."
Morsecode("D") = "-.."
Morsecode("E") = "."
Morsecode("F") = "..-."
Morsecode("G") = "--."
Morsecode("H") = "...."
Morsecode("I") = ".."
Morsecode("J") = ".---"
Morsecode("K") = "-.-"
Morsecode("L") = ".-.."
Morsecode("M") = "--"
Morsecode("N") = "-."
Morsecode("O") = "---"
Morsecode("P") = ".--."
Morsecode("Q") = "--.-"
Morsecode("R") = ".-."
Morsecode("S") = "..."
Morsecode("T") = "-"
Morsecode("U") = "..-"
Morsecode("V") = "...-"
Morsecode("W") = ".--"
Morsecode("X") = "-..-"
Morsecode("Y") = "-.--"
Morsecode("Z") = "--.."

Procedure playdit()
  PlaySound(ditsnd)
  Delay(speedms*2)
EndProcedure

Procedure playdah()
  PlaySound(dahsnd)
  Delay(speedms*4)
EndProcedure

Procedure playspace()
  Delay(speedms*8)
EndProcedure

Procedure output(morse.s)
  Define i.i
  For i = 1 To Len(morse)
    Select Mid(morse, i, 1)
      Case "."
        playdit()
      Case "-"
        playdah()
      Case " "
        playspace()
    EndSelect
  Next
  Delay(speedms)
EndProcedure

Procedure process(text.s)
  text = UCase(text)
  If text = "QUIT"
    End
  EndIf
  Define i.i
  Define now.s
  For i = 1 To Len(text)
    now = Mid(text, i, 1)
    If Morsecode(now) <> ""
      Print(now)
      output(Morsecode(now))
    EndIf
  Next
  PrintN("")
EndProcedure

OpenConsole("minimorse")
PrintN("Welcome to minimorse.")
PrintN("")
PrintN("Space and a-z will be recognized.")
PrintN("CH will be treated as separate characters - despite ITU.")
PrintN("All other chars will be discarded.")
PrintN("If you want to improve: alter Morsecode map and rewrite")
PrintN("process proc for an advanced tokenizer and have fun!")
PrintN("Enter some text now. If you want to quit, enter quit.")
PrintN("")

Define input.s
Repeat
  Print("input: ")
  input = Input()
  process(input)  
ForEver
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 536
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: SoundEasy.pbi include file adds CreateSound() command

Post by BasicallyPure »

gekkonier wrote:I know, old thread, but this rocks!
Glad you liked it.
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
gekkonier
User
User
Posts: 78
Joined: Mon Apr 23, 2007 9:42 am

Re: SoundEasy.pbi include file adds CreateSound() command

Post by gekkonier »

Hi BasicallyPure,

I've used your code in my own little Morse Learning program:
http://forum.purebasic.com/english/view ... 27&t=65698

Have a nice day and thank you,
Gekko
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: SoundEasy.pbi include file adds CreateSound() command

Post by collectordave »

Just had this pointed out to me great. Used for Beep. Could get some really fancy beeps in my application now.

Where have I been?

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Post Reply