Android Question Beeper function distorts

goldmagnet

Member
Licensed User
Longtime User
Hello

The B4A beeper function is not ideal for my app because of the distortion it produces (see attached recording trace). When using the beeper a loud click is produced at the end, when producing short beeps < 50 ms the click is pretty much all you hear (I have tested on lots of devices, its not a device effect).

I believe the reason for this is that it is classical broadband distortion caused by terminating the signal at a high level, according to the functions instructions (beep for n milliseconds the stop).

My ideal beeper would be the same but it would terminate as the signal crossed the x axis at zero amplitude, which I believe would result in a clean beep, at very slightly the wrong duration (negligible).

I have tried to implement this with a streamer, using one of Erel's examples, but the buffering causes issues at these low beep durations.

Any ideal how to implement this ?

Thanks

Huw
 

Attachments

  • click.JPG
    click.JPG
    37.9 KB · Views: 244

goldmagnet

Member
Licensed User
Longtime User
Hi Colin

I don't think thats suitable, I need to generate short duration at specific frequency at run time.

Huw
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
The "recorded audio" file you can play with Soundpool can be of a short duration and of a specific frequency - just record the file to the exact specifications you want to play.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hi Colin

I don't think thats suitable, I need to generate short duration at specific frequency at run time.

Huw
Are you using multiple different frequencies, or just one? If just one, you could record it & use SoundPool. Actually, you can do it for multiple different frequencies too - unless you need to generate them randomly, in which case it might get cumbersome having to record every single possibility...

- Colin.
 
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
It can be any frequency between 300 and 1100, and any duration between 15ms and 500ms.

I have not done the math but I could die before I recorded those files, so no thats not a possibility.

Huw
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
There are websites that can generate sound files where you specify the frequency and duration.

Then just play the generated file using soundpool.

 
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
There are websites that can generate sound files where you specify the frequency and duration.

Then just play the generated file using soundpool.


Embedding 800 sound files into an app is not a solution I want to pursue..

"It can be any frequency between 300 and 1100, and any duration between 15ms and 500ms. "
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
I did not know you had to generate that huge amount of different sounds.

No sound player will work for your needs. You need to find a tone generator library that can programmically generate all the notes you need.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
This is the relevant link for creating a beep sound with AudioStreamer: https://www.b4x.com/android/forum/threads/audio-library-beeper-duration.78712/#post-498840
It is the same implementation as the Beeper object.

I guess that you should be able to customize it and stop the playback at a different point.

Hello Erel. Yes I found that example some time ago and thought the same. The trouble is when you use a streamer to create a sound that is only 20ms long you cant seem to flush it out of the buffer. I spent a few hours with that example and while it works great with longer sounds, the short pulses will not work.

If I have made a mistake then would be overjoyed to find it, but I can find no way to play a short duration beep other than beeper that has this spike. As I am using it to create/modulate a data signal then the spike is very important.

Thanks.

Huw
 
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
Erel that code would be perfect if I could get the data out the buffer reliably.

Heres a look at the audio with you code, then same frequency with the beeper, your code produces perfect audio, just need to be able to reliably get it out of the buffer..
 

Attachments

  • click2.JPG
    click2.JPG
    58.5 KB · Views: 220
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try this modified version which reduces the volume to 0 before it stops:
B4X:
Public Sub Beep (DurationMs As Double, Frequency As Int)
    Dim sampleRate As Int = 8000
    Dim numSamples As Int = sampleRate * DurationMs / 1000
    Dim MaxVal As Short = 32767
    Dim gsnd(2 * numSamples) As Byte
    Dim Fade As Int = (numSamples / 100) * 95
    For i = 0 To numSamples - 1
        If i > Fade Then MaxVal = MaxVal * 0.95
        Dim d As Double = Sin(2 * cPI * i / (sampleRate / Frequency))
        Dim val As Short = d * MaxVal
        gsnd(2 * i) = Bit.And(val, 0x00ff)
        gsnd(2 * i + 1) = Bit.UnsignedShiftRight(Bit.And(val, 0xff00), 8)
    Next
    streamer.Write(gsnd)
End Sub

It could be improved by using a logarithmic fade out and calculating an appropriate fade out start point rather than just 95%.
 
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
Thanks so much Erel & Steve.

Steve that looks much better see attached (just sending zero values in between signals).
 

Attachments

  • clicksteve.JPG
    clicksteve.JPG
    64.9 KB · Views: 219
Upvote 0

goldmagnet

Member
Licensed User
Longtime User
Now fully implemented, thanks Erel & Steve, I now have a readable data stream....

Thank you.
 

Attachments

  • click4.JPG
    click4.JPG
    102.3 KB · Views: 235
Upvote 0
Top