Audio beep @ 192k and 24 bits

Just starting out? Need help? Post your questions and find answers here.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Audio beep @ 192k and 24 bits

Post by Simo_na »

Hi,
i would like to create an audio beep @ 192k and 24 bits, is doable with Purebasic ?
Thankyou
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Yes, it's possible and no, it is not.

In theorie:
You have to create a wav file 'on the fly' and play it.
There are already examples in the forum.

http://www.purebasic.fr/english/viewtop ... 13&t=57604

And no, because I don't think you'll have a soundcard which can play this.

A normal soundcard is able to play arround 30kHz.
But then you have the next problem: the loudspeaker.
Maybe some piezo horn tweeters can reach this too.

But 192kHz :?: :?: :?:

That's already RF :!:

For something like that you can use a fast microcontroller, an D/A converter (or R2R ladder),
a RF amplifier and a longwave antenna.
And ... a radio amateur license.

Or do you simply forgot a point: 19.2kHz ?

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

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

First thank you for your time :)
I have a RME soundcard with 56 channels and 24Bit 192KHz. (192000)
I will find a 192KHz and 24Bit sinewave (sine@1KHz) or long beep to send @ external measurement device for loopback test
Any loudspeakers are present for now in the auido chain.
If do a 'synthesis' even better.
I have seen most coder write for 16Bit and 44100KHz or less :oops: :oops:
:D
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Oh...

you mean the samplerate.
I meant you mean the frequency of the beep.

So it should be possible with the way I showed you:

Create a wav on the fly and simply play it.
If the sounddriver can handle it, it will work.

Bernd
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Example:

Code: Select all

EnableExplicit

Structure RIFFStructure
  Riff.a[4]
  Length.l
  Wave.a[4]
EndStructure


Structure fmtStructure
  fmt.a[4]
  Length.l
  Format.u
  Channels.u
  SampleRate.l
  BytesPerSecond.l
  BlockAlign.u
  BitsPerSample.u
EndStructure


Structure dataStructure
  Signature.a[4]
  Length.l
EndStructure



Procedure.i CreateSineWAV(*WAVBuffer)
  
  Protected.i Result, dataOffset, Ptr, i, Value
  Protected *RiffPtr.RIFFStructure, *fmtPtr.fmtStructure, *dataPtr.dataStructure
  
  If *WAVBuffer
    
    *RiffPtr = *WAVBuffer
    PokeS(@*RiffPtr\Riff, "RIFF", 4, #PB_Ascii|#PB_String_NoZero)
    PokeS(@*RiffPtr\Wave, "WAVE", 4, #PB_Ascii|#PB_String_NoZero)
    
    *fmtPtr = *WAVBuffer + SizeOf(RIFFStructure)
    PokeS(@*fmtPtr\fmt, "fmt ", 4, #PB_Ascii|#PB_String_NoZero)
    *fmtPtr\Length = SizeOf(fmtStructure) - 8
    *fmtPtr\Format = 1
    *fmtPtr\Channels = 1
    *fmtPtr\SampleRate = 192000
    *fmtPtr\BitsPerSample = 24
    *fmtPtr\BlockAlign = *fmtPtr\Channels * ((*fmtPtr\BitsPerSample + 7) / 8)
    Debug *fmtPtr\BlockAlign
    *fmtPtr\BytesPerSecond = *fmtPtr\SampleRate * *fmtPtr\BlockAlign
    
    
    *dataPtr = *WAVBuffer + SizeOf(RIFFStructure) + SizeOf(fmtStructure)
    PokeS(@*dataPtr\Signature, "data", 4, #PB_Ascii|#PB_String_NoZero)
    
    dataOffset = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure)
    
    Ptr = 0
    For i = 0 To 360
      Value = Sin(Radian(i)) * 8388607  ; 2^24 / 2 - 1
      Debug Value
      PokeA(*WAVBuffer + dataOffset + Ptr, Value & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 8) & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 16) & $FF)
      Ptr + 1
    Next i
    
    *dataPtr\Length = Ptr
    *RiffPtr\Length = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure) + Ptr - 8
    
    Result = *RiffPtr\Length + 8
    
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


InitSound()

Define *Buffer, Length.i

*Buffer = AllocateMemory(10240)
If *Buffer
 
  Length = CreateSineWAV(*Buffer)
  If Length
    
;     If CreateFile(0, "c:\tmp\test.wav")
;       WriteData(0, *Buffer, Length)
;       CloseFile(0)
;     EndIf
    
    Debug "Created"
    If CatchSound(0, *Buffer, Length)
     
      Debug "Play"
      PlaySound(0, #PB_Sound_Loop)
      Delay(1000)
      StopSound(0)
      
    EndIf
  EndIf
 
  FreeMemory(*Buffer)
EndIf
If you comment out the 'save' stuff you get a wav file which you can also play or inspect with an external tool.
But if the sound is really played with the desiered rate and bits .... who know.
I don't know a method to test this.

Bernd
Last edited by infratec on Fri May 08, 2015 7:33 pm, edited 2 times in total.
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Made the listing above unicode aware.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

Thank you. :)
With you code the sine wave on the Spectrum Analyzer result with many errors of harmonics,
instead this sinewave
http://www.purebasic.fr/english/viewtop ... 29#p431329
is ok but is @ 16bit :oops: :cry:
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Hi,

you can try this:

Code: Select all

Procedure.i CreateSineWAV(*WAVBuffer, Freq.i=440)
 
  Protected.i Result, dataOffset, Ptr, i, Value
  Protected.f SineStep, r
  Protected *RiffPtr.RIFFStructure, *fmtPtr.fmtStructure, *dataPtr.dataStructure
 
  If *WAVBuffer
   
    *RiffPtr = *WAVBuffer
    PokeS(@*RiffPtr\Riff, "RIFF", 4, #PB_Ascii|#PB_String_NoZero)
    PokeS(@*RiffPtr\Wave, "WAVE", 4, #PB_Ascii|#PB_String_NoZero)
   
    *fmtPtr = *WAVBuffer + SizeOf(RIFFStructure)
    PokeS(@*fmtPtr\fmt, "fmt ", 4, #PB_Ascii|#PB_String_NoZero)
    *fmtPtr\Length = SizeOf(fmtStructure) - 8
    *fmtPtr\Format = 1
    *fmtPtr\Channels = 1
    *fmtPtr\SampleRate = 192000
    *fmtPtr\BitsPerSample = 24
    *fmtPtr\BlockAlign = *fmtPtr\Channels * ((*fmtPtr\BitsPerSample + 7) / 8)
    Debug *fmtPtr\BlockAlign
    *fmtPtr\BytesPerSecond = *fmtPtr\SampleRate * *fmtPtr\BlockAlign
   
   
    *dataPtr = *WAVBuffer + SizeOf(RIFFStructure) + SizeOf(fmtStructure)
    PokeS(@*dataPtr\Signature, "data", 4, #PB_Ascii|#PB_String_NoZero)
   
    dataOffset = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure)
   
    Ptr = 0
    SineStep = #PI * 2 * Freq / *fmtPtr\SampleRate
    r = 0
    Repeat
      Value = Sin(r) * 8388607  ; 2^24 / 2 - 1
      r + SineStep
      Debug Value
      PokeA(*WAVBuffer + dataOffset + Ptr, Value & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 8) & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 16) & $FF)
      Ptr + 1
    Until r >= #PI * 2
    
    Debug Ptr / 3
    
    *dataPtr\Length = Ptr
    *RiffPtr\Length = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure) + Ptr - 8
   
    Result = *RiffPtr\Length + 8
   
  EndIf
 
  ProcedureReturn Result
 
EndProcedure
Maybe it comes from playing a loop.
I only generate one sine wave and it is played in a loop.
If the player is not fast enough, it can result in distortions.

Maybe I extend it to generate the right length of the beep.

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

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

I have experienced :)
It is much better but it is still distorted
the screenshot :
Image
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Ok,

try this:

Code: Select all

EnableExplicit

Structure RIFFStructure
  Riff.a[4]
  Length.l
  Wave.a[4]
EndStructure


Structure fmtStructure
  fmt.a[4]
  Length.l
  Format.u
  Channels.u
  SampleRate.l
  BytesPerSecond.l
  BlockAlign.u
  BitsPerSample.u
EndStructure


Structure dataStructure
  Signature.a[4]
  Length.l
EndStructure



Procedure.i CreateSineWAV(*WAVBuffer, Freq.i=440, DurationMs.i=500)
 
  Protected.i Result, dataOffset, Ptr, i, Value, MaxAmp
  Protected.f SineStep, r
  Protected *RiffPtr.RIFFStructure, *fmtPtr.fmtStructure, *dataPtr.dataStructure
 
  If *WAVBuffer
   
    *RiffPtr = *WAVBuffer
    PokeS(@*RiffPtr\Riff, "RIFF", 4, #PB_Ascii|#PB_String_NoZero)
    PokeS(@*RiffPtr\Wave, "WAVE", 4, #PB_Ascii|#PB_String_NoZero)
   
    *fmtPtr = *WAVBuffer + SizeOf(RIFFStructure)
    PokeS(@*fmtPtr\fmt, "fmt ", 4, #PB_Ascii|#PB_String_NoZero)
    *fmtPtr\Length = SizeOf(fmtStructure) - 8
    *fmtPtr\Format = 1
    *fmtPtr\Channels = 1
    *fmtPtr\SampleRate = 192000
    *fmtPtr\BitsPerSample = 24
    *fmtPtr\BlockAlign = *fmtPtr\Channels * ((*fmtPtr\BitsPerSample + 7) / 8)
    ;Debug *fmtPtr\BlockAlign
    *fmtPtr\BytesPerSecond = *fmtPtr\SampleRate * *fmtPtr\BlockAlign
   
   
    *dataPtr = *WAVBuffer + SizeOf(RIFFStructure) + SizeOf(fmtStructure)
    PokeS(@*dataPtr\Signature, "data", 4, #PB_Ascii|#PB_String_NoZero)
   
    dataOffset = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure)
   
    Ptr = 0
    SineStep = #PI * 2 * Freq / *fmtPtr\SampleRate
    r = 0
    MaxAmp = ((2 << (*fmtPtr\BitsPerSample - 2)) - 1) * 0.8
    Repeat
      Value = Sin(r) * MaxAmp
      r + SineStep
      If r > #PI * 2 : r - #PI * 2 : EndIf
      ;Debug Value
      PokeA(*WAVBuffer + dataOffset + Ptr, Value & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 8) & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 16) & $FF)
      Ptr + 1
      ;Until r >= #PI * 2
    Until Ptr >=  *fmtPtr\BytesPerSecond / 1000 * DurationMs
    
    ;Debug Ptr / 3
    
    *dataPtr\Length = Ptr
    *RiffPtr\Length = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure) + Ptr - 8
   
    Result = *RiffPtr\Length + 8
   
  EndIf
 
  ProcedureReturn Result
 
EndProcedure


InitSound()

Define *Buffer, Length.i

*Buffer = AllocateMemory(1024000)
If *Buffer
 
  Length = CreateSineWAV(*Buffer, 440, 500)
  If Length
   
    If CreateFile(0, "c:\tmp\test.wav")
      WriteData(0, *Buffer, Length)
      CloseFile(0)
    EndIf
   
    Debug "Created"
    If CatchSound(0, *Buffer, Length)
     
      Debug "Play"
      ;PlaySound(0, #PB_Sound_Loop)
      ;Delay(1000)
      ;StopSound(0)
      
      PlaySound(0)
      While SoundStatus(0) = #PB_Sound_Playing
        Delay(10)
      Wend
     
    EndIf
  EndIf
 
  FreeMemory(*Buffer)
EndIf
You can now also set the duration of the beep in ms.
Now you should have no distortions, since it is a complete sine wave file.
But it is larger.

Bernd
Last edited by infratec on Wed May 13, 2015 10:58 pm, edited 2 times in total.
Simo_na
Enthusiast
Enthusiast
Posts: 177
Joined: Sun Mar 03, 2013 9:01 am

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

:D
i've added a global 'dur' variable (duration)
Now it's almost right, but you hear three frequency shift when PlaySound still in progress ?
the code:

Code: Select all

;Sine - Tone - 192000 Hz - 24 Bit
;Coded By INFRATEC - 2015 - Beta

EnableExplicit

Structure RIFFStructure
  Riff.a[4]
  Length.l
  Wave.a[4]
EndStructure


Structure fmtStructure
  fmt.a[4]
  Length.l
  Format.u
  Channels.u
  SampleRate.l
  BytesPerSecond.l
  BlockAlign.u
  BitsPerSample.u
EndStructure


Structure dataStructure
  Signature.a[4]
  Length.l
EndStructure

Global dur=64000*256 ; ___duration

Procedure.i CreateSineWAV(*WAVBuffer, Freq.i=440, DurationMs.i=500)
 
  Protected.i Result, dataOffset, Ptr, i, Value, MaxAmp
  Protected.f SineStep, r
  Protected *RiffPtr.RIFFStructure, *fmtPtr.fmtStructure, *dataPtr.dataStructure
 
  If *WAVBuffer
   
    *RiffPtr = *WAVBuffer
    PokeS(@*RiffPtr\Riff, "RIFF", 4, #PB_Ascii|#PB_String_NoZero)
    PokeS(@*RiffPtr\Wave, "WAVE", 4, #PB_Ascii|#PB_String_NoZero)
   
    *fmtPtr = *WAVBuffer + SizeOf(RIFFStructure)
    PokeS(@*fmtPtr\fmt, "fmt ", 4, #PB_Ascii|#PB_String_NoZero)
    *fmtPtr\Length = SizeOf(fmtStructure) - 8
    *fmtPtr\Format = 1
    *fmtPtr\Channels = 1
    *fmtPtr\SampleRate = 192000
    *fmtPtr\BitsPerSample = 24
    *fmtPtr\BlockAlign = *fmtPtr\Channels * ((*fmtPtr\BitsPerSample + 7) / 8)
    Debug *fmtPtr\BlockAlign
    *fmtPtr\BytesPerSecond = *fmtPtr\SampleRate * *fmtPtr\BlockAlign
   
   
    *dataPtr = *WAVBuffer + SizeOf(RIFFStructure) + SizeOf(fmtStructure)
    PokeS(@*dataPtr\Signature, "data", 4, #PB_Ascii|#PB_String_NoZero)
   
    dataOffset = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure)
   
    Ptr = 0
    SineStep = #PI * 2 * Freq / *fmtPtr\SampleRate
    r = 0
    MaxAmp = ((2 << (*fmtPtr\BitsPerSample - 2)) - 1) * 0.8
    Repeat
      Value = Sin(r) * MaxAmp
      r + SineStep
      ;Debug Value
      PokeA(*WAVBuffer + dataOffset + Ptr, Value & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 8) & $FF)
      Ptr + 1
      PokeA(*WAVBuffer + dataOffset + Ptr, (Value >> 16) & $FF)
      Ptr + 1
      ;Until r >= #PI * 2
    Until Ptr >=  dur ; ___duration
   
    ;Debug Ptr / 3
   
    *dataPtr\Length = Ptr
    *RiffPtr\Length = SizeOf(RIFFStructure) + SizeOf(fmtStructure) + SizeOf(dataStructure) + Ptr - 8
   
    Result = *RiffPtr\Length + 8
   
  EndIf
 
  ProcedureReturn Result
 
EndProcedure


InitSound()

Define *Buffer, Length.i

*Buffer = AllocateMemory(dur*2) ; ___duration
If *Buffer
 
  Length = CreateSineWAV(*Buffer, 440, dur) ; ___duration
  If Length
   
    If CreateFile(0, "c:\tmp\test.wav")
      WriteData(0, *Buffer, Length)
      CloseFile(0)
    EndIf
   
    Debug "Created"
    If CatchSound(0, *Buffer, Length)
     
      Debug "Play"
      ;PlaySound(0, #PB_Sound_Loop)
      ;Delay(1000)
      ;StopSound(0)
     
      PlaySound(0)
      While SoundStatus(0) = #PB_Sound_Playing
        Delay(20)
      Wend

     
    EndIf
  EndIf
 
  FreeMemory(*Buffer)
EndIf
PS
The file is about 16 MB
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Hi,

why the global dur variable?

Hm, you should not hear different frequenzies.
Can you hear them also if you load the file in an external player?
(Audacity)

Maybe the middle way would be optimal:
Generate the sound for 100ms and play it in a loop how long you need it.
Then the used memory stays low and the distortions should be small enough.

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

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

:)
global 'dur' variable is an arrangement for possibile modify the time of loopback with a small gui interface 8)
I used Soundforge Pro and skidding is present also with him. :oops:
for the distortion, now is acceptable :)
so just keep the frequency stable if it is possible and the code is perfect. :D
click for screenshot:
Image
infratec
Always Here
Always Here
Posts: 7625
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Audio beep @ 192k and 24 bits

Post by infratec »

Hi,

I can not reproduce your problem.
Recorded 5 seconds:

Image

Changed the until loop because of an overflow :wink:

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

Re: Audio beep @ 192k and 24 bits

Post by Simo_na »

What kind of software do you use ? :D
Post Reply