B4A Library Audio library v1.5 - New AudioStreamer object

Status
Not open for further replies.
This version includes a new AudioStreamer type. Note that this is a beta version (for this type only).

The purpose of AudioStreamer is to make it simple to stream audio from the microphone and to the speakers. Internally it is based on AudioTrack and AudioRecord.

Next week I plan to create an example of streaming audio between two devices (walkie-talkie app).

Recording is done by calling StartRecording. The RecordBuffer event will be raised multiple times during the recording:
B4X:
Sub streamer_RecordBuffer (Buffer() As Byte)
   'collect the recording data
   buffers.Add(Buffer)
End Sub
You can write this data to a file or as done in this example, collect the buffers in a list. Later we will use this list to play the recording:
B4X:
Sub btnPlay_Click
   btnStartRecording.Enabled = False
   streamer.StartPlaying
   For Each b() As Byte In buffers
      streamer.Write(b)
   Next
   streamer.Write(Null) 'when this "message" will be processed, the player will stop.
End Sub
Note that the player has an internal queue. The write method will not block the main thread. The data is just added to the queue. It is processed by another thread.

SS-2013-06-26_17.07.34.png


An example of saving the recording to a wave file is available in post #10.
Walkie-Talkie example is available here.


V1.62 is attached. It adds an Error event. This event will be raised when an error happens during recording.
New method: AudioStreamer.Initialize2.
It allows you to set the audio source. The value should be one of the values listed here: http://developer.android.com/reference/android/media/MediaRecorder.AudioSource.html
For example to set the audio source to the voice call channel you will use the value 4.
 

Attachments

  • AudioStreamerExample.zip
    10.4 KB · Views: 317
Last edited:

birdwes

Member
Licensed User
Just found a really useful and reasonably easy to read e-book for anyone doing audio or visual processing (which is also available in hardback) here: http://www.dspguide.com/ .

I found the link in this: http://documentation.renesas.com/doc/DocumentServer/U17285EE2V0AN00.pdf

I'm looking at implementing a hyper fast version of the FFT on Page 31 (I've already heavily refactored it in C - test-bench on the PC) in a hybrid of C and ARMv6 assembler; I am thinking of making a demo going right down from B4A though a Java wrapper into JNI (I don't really know Java so I have to get into C as quickly as possible), into C and finally down into ARM assembler.

I'm sure this would be a useful demo, as I looked for one and can't find it! (I need it for my hobby project as the first approximation).

You can see some of my other ARM work here: http://sourceforge.net/p/raspbx/discussion/general/thread/366d6ec4/ . I got a speedup by a factor of 10 (from the C version, to hybrid C / assembler) on the Raspberry Pi, so we could be looking at an even bigger jump from B4A compiled to Java?

I learned assembler on 6502 which is why I'm very comfortable with ARM, but please can someone else help with an Intel or MIPS version?
 
Last edited:

birdwes

Member
Licensed User
B4A to JNI and beyond (ARM Assembler) Demo will be soon (4-6 weeks?),

I've got the inner loop of the first two iterations of something based on

http://documentation.renesas.com/doc/DocumentServer/U17285EE2V0AN00.pdf page 34

down to 23.5 clock cycles tested on the Raspberry Pi (ARMv6)

http://pulsar.webshaker.net/ccc/sample-45fcc92c

Surprisingly accurate for a 16 bit Fixed point implementation e.g. 48K sample 4096 fft:
better than 0.01Hz - 1 to 10 parts per million. Resolution is governed by FFT bin width
(I.E. 48000/4096 = 11.7Hz)
( i.e. if you have two tones within three bin widths, then they will be "smeared" into an average - you have to use another technique to distinguish them ;-)
 
Last edited:

birdwes

Member
Licensed User
It's now a triple target audience as I have BeagleBone Black too now. We will be supporting NEON extensions too.
 

kiki78

Active Member
Licensed User
Just a warning for user of this library.

I use RecordBuffer event and I lost some time to understand why I have not correct signal when I convert Data Byte array to Short.
Explanation is you receive LittleEndian data as Windows and not BigEndian as expected from Android.
I suppose this is to simplify wav file recording.
So, for example, if like me you use ByteConverter.ShortsFromBytes to convert byte array to samples value, don't forget to set your ByteConverter object LittleEndian property to True.

Regards
 

GMan

Well-Known Member
Licensed User
Hoi,
is it possible to set the recording volume to the highest value before or just when starting a new record ?
 

GMan

Well-Known Member
Licensed User
Thx - so this comes from the OS
 

GMan

Well-Known Member
Licensed User
is it possible to start with the photo -modus instead with the camera -modus ?

I know you can change it with a click in the event window, but only for complete understanding i wanna know this, too.
AND iw ould save space for an (maybe needed) additional library
 

GMan

Well-Known Member
Licensed User
Solved, Erel - mea culpa
 

freedom2000

Well-Known Member
Licensed User
Hi,

Thank you for this excellent lib that I have already used for my "Secret Recorder"

A friend of mine is really interested into music (guitar player) and is very concerned by "lag" between real time music and audio return via earphones.
He would like to do some real time tuning of his electrical guitar while playing.
Audio streamer is of course a very good candidate but the audio buffers are sent when the buffer is full...
For 44kHz sampling and an average of 2048 buffer size the delay between the first sample and the audio return channel should be :
2048/44000 = 0.046 s ie 46ms.
From his own experience more than 10 ms will cause a "perception problem" for the musician (an unbearable desynchronisation).

So is there a way to speed up the RecordBuffer_event frequency ?

thanks
 

freedom2000

Well-Known Member
Licensed User
Another question !

Does it exist a way to simultaneously record/input the audio stream (from an external microphone for example) AND output it (after optional processing) in real time to the loudspeaker ?

I made a (very) dirty modification to allow both Record and Play buttons visible on the audio record example, something happens but the sound is not clean... (even after waiting a few sec to fill the buffers)

B4X:
Sub btnStartRecording_Click
    buffers.Clear
    streamer.StartRecording
    recordingStart = DateTime.Now
End Sub

Sub btnPlay_Click
    streamer.StartPlaying
    For Each b() As Byte In buffers
        streamer.Write(b)
    Next
    streamer.Write(Null) 'when this "message" will be processed, the player will stop.
End Sub
 

Erel

Administrator
Staff member
Licensed User
The buffer size is determined with a call to this API:
AudioRecord.getMinBufferSize(SampleRate,channelConfig, audioFormat);

This is the minimum acceptable buffer size based on the parameters.

The input and output features are not related to each other. You can use them both at the same time. You will encounter a "positive feedback" problem if the microphone will catch the output.

See the walkie talkie example: Walkie Talkie - Audio streaming over Wifi or Bluetooth
 

freedom2000

Well-Known Member
Licensed User
The buffer size is determined with a call to this API:
AudioRecord.getMinBufferSize(SampleRate,channelConfig, audioFormat);

This is the minimum acceptable buffer size based on the parameters.

The input and output features are not related to each other. You can use them both at the same time. You will encounter a "positive feedback" problem if the microphone will catch the output.

See the walkie talkie example: Walkie Talkie - Audio streaming over Wifi or Bluetooth

Thank you again for your efficiency ...

This is however half a good news for me !
I understand that I can't change the buffer size because its minimum size is fiwed by the OS

Still another question :
I saw many other "Phone Recorders" which give the choice for the recorded stream.
It is classically :
  • default
  • micro
  • up voice call
  • down voice call
  • line
Would it be difficult to with audio streamer library to add this parameter ?
 
Status
Not open for further replies.
Top