B4A Library AudioRecord Library

This is an Audio Recording Library based on the Android AudioRecord object which allows capturing of sound input to a data file for further processing (maybe realtime if we're lucky).

Included in the demo program is a WAV file header routine that allows saving captured sound as an uncompressed wav file.

Please read the documentation of the AudioRecord object. It's a little more complicated that the media recorder version, but gives additional flexibility.

Please test it and hopefully we can get it to work well for us.

Added libs 1.01 - Additional constants and Capitalized

12/6/2012 Artest updated to better manage thread on closedown.

For use with V2 of B4a (more specifically the latest threading library) you'll need to add a parameter to the start thread call in artest. Line 89, Record.Start("Recording",Null) becomes Record.Start(Null,"Recording",Null)

artest 1155
 

Attachments

  • AudioRecord1.01.zip
    4.9 KB · Views: 3,047
  • artest1.02.zip
    8.2 KB · Views: 1,243
Last edited:

stevel05

Expert
Licensed User
Longtime User
If it works for you as it is, that's fine. It could be a lot more robust, it was only intended as an example.

If you release the recorder resources, you should be able to initialize it again I believe, you'll need to check it, along with catching and dealing with orientation changes and other android lifecycle issues.
 

madSac

Active Member
Licensed User
Longtime User
If it works for you as it is, that's fine. It could be a lot more robust, it was only intended as an example.

If you release the recorder resources, you should be able to initialize it again I believe, you'll need to check it, along with catching and dealing with orientation changes and other android lifecycle issues.
Finally, I tried it in service it worked fine and i found a error which can cause a lot of hassle
B4X:
DateTime.Now > StartTime + "10000"
'it compared with start time and will be always true so it should be
DateTime.Now > (StartTime + "10000")
 

KZero

Active Member
Licensed User
Longtime User
on note 2 8KHZ,16KHZ,32KHZ,48KHZ is working
on galaxy pocket all working except 32KHZ !!!


any idea if its possible to fix ?
 

stevel05

Expert
Licensed User
Longtime User
It's possible that the hardware doesn't support it. I found a comment about older Samsung phones not supporting 32 Khz recording, so it may still apply to the pocket. I couldn't find anything specific though.
 

KZero

Active Member
Licensed User
Longtime User
It's possible that the hardware doesn't support it. I found a comment about older Samsung phones not supporting 32 Khz recording, so it may still apply to the pocket. I couldn't find anything specific though.

ok thx m8
 

CarlM

Member
Licensed User
Longtime User
Original post by UriKupfer.
I wrote a little program just to learn how to analyze in "real time" fft ,on the mic data ,
The program doesn’t have any help ' and it's just in the start phase, but it demonstrate the use
Of this library

Uri,

Do you still have the program you wrote? I have been trying to capture a single period for use in fft to obtain the frequency but have had no success. Any help would be appreciated. The trouble is I don't know what the frequency of the input data will be so its pretty hard to iscolate a single period, especially if the audio has overtones (ie: not a simple sine wave).
Many thanks.
 
Last edited:

ianrich

Member
Licensed User
Longtime User
Hi,
I've been working with the example artest and it runs ok, however, there is an issue with:
Sub Rec_Ended(endedOK As Boolean, Error As String).
:signOops:
The boolean endedOK always returns False, UpdateHeader doesn't run so DataSize is never written to the wav file header.

Note that the file still plays on the Android device. However, if you look at the file in a hex editor you see the header shows 0 datasize. Windows Media Player is unable to play the .wav like this, VLC can play it.

I've tried a few changes but have not yet been able to resolve it. Any suggestions would be most welcome, thanks.
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Rec_Ended is called by the threading library when the thread finishes, is there an error returned?

The App doesn't really need the threading library, it was part of an experiment, you could rewrite it without the threading, or if there is not an obvious error and you are happy that the recording is complete, you could just ignore the error and write the datasize regardless.
 

ianrich

Member
Licensed User
Longtime User
Thanks for your reply Steve. The issue was with using Record.Interrupt to stop recording and it just closed the thread.
:sign0060:
I got it to work by setting a flag to end recording and moved the Rec_Ended code into the Recording loop as below...

B4X:
If RecEnding = True Then
   Try
      AR.Stop
      AR.release
   Catch
   End Try   
   UpdateHeader
   Record.Interrupt
End If
If Record.IsInterrupted then Exit

The Sub Rec_Ended endedOK now returns True without error and the .wav file has the correct datasize.

Now I'd like to be able to play two mono wav files at the same time. I read some comments that the way to combine them is to merge them into another file. This, however, doesn't suit my purpose as I want them to play in real time so maybe there's a way they can be kept in sync by using a clock. Any thoughts regarding this approach or how it might be implemented?
 

stevel05

Expert
Licensed User
Longtime User
You don't need to merge them to another file, you can just merge them to an array within the program with appropriate normalization (making sure the levels aren't too high).

If you create two players, you won't be able to guarantee syncing and it would be likely to give different results using different hardware.
 

ianrich

Member
Licensed User
Longtime User
You don't need to merge them to another file, you can just merge them to an array within the program with appropriate normalization (making sure the levels aren't too high).

Much appreciate your guidance Steve. I'm trying to merge two tracks but unsure on syntax for adding the byte arrays. Do I need to use the ByteConverter library and is there any example code anywhere that might assist? :sign0085: Thanks...
 

stevel05

Expert
Licensed User
Longtime User
Here is a quick and dirty example, I'm sure there is probably a better (more efficient) way to add the two arrays together, but it is proof of concept.

I've removed the threading as well as there is no benefit to having it in there.

Hope it helps.
 

Attachments

  • mixtest.zip
    334.2 KB · Views: 337
Last edited:

ianrich

Member
Licensed User
Longtime User
I'm sure there is probably a better (more efficient) way to add the two arrays together, but it is proof of concept..
:sign0188:
Yes, I have it working. The actual array copying takes about 15 seconds to process 3-4 seconds of audio so real-time processing isn't an option. However, I'll endeavor to optimize it further. Any suggestions in this respect would be most welcome, many thanks.
 

stevel05

Expert
Licensed User
Longtime User
That's great, there is a lot of info on the internet about mixing sounds. There are apparently many ways to achieve good results have a look here for a short discussion.

Andrew Graham as provided an fft library which may help if you want to delve deeper.
 

ianrich

Member
Licensed User
Longtime User
I did some logging and notice that there a several 3-second pauses (like the processor is busy doing something else) during the array copying. That seems very odd and I'd like to know what's making it behave that way.

I will explore the links you posted, many thanks.
 

stevel05

Expert
Licensed User
Longtime User
I hadn't noticed that here although it is susceptible to other processing running and slowing it down.

Here's another version that uses shorts throughout. It should be a bit quicker.

I've changed the samples as the others were the wrong sample rate and playing back at the wrong speed. Correcting that made them too big.
 

Attachments

  • mixTest2.zip
    99.7 KB · Views: 319

ianrich

Member
Licensed User
Longtime User
I'm really appreciating your help, thanks.

I managed to limit the delays on the "byte" version by using vars for ShortFile.Size and LongFile.Size on the loop. I think your Shorts version has improved the speed again, however, it would seem there's quite a leap to get running close to real time. Anyway, will continue look at further refinement. My thought is to have the audio playing as soon as there's some data available in OutArray but it may not be able to keep up with that...
 

stevel05

Expert
Licensed User
Longtime User
Yes, unfortunately real time audio on Android is still a long way off.

Here's another version for which I have created a minimal ShortBuffer Library with just three of the methods implemented, I think it's slightly quicker again.

If you think any more methods would be useful I can add them or let you have the Eclipse source code if you can/want to do it yourself (or use Erel's Simple Library Compiler).

Unzip both of the files from ShortBufferLib.zip to your addl libs folder, refresh the libs tab (right click) and select the ShortBuffer Lib.
 

Attachments

  • mixTest3.zip
    99.8 KB · Views: 293
  • ShortBufferLib.zip
    1.9 KB · Views: 247
Last edited:

stevel05

Expert
Licensed User
Longtime User
Ok one last update for now, this one adds a get to the buffer and can be used entirely instead of copying back to an array.

I'm not sure there is any more speed improvement, but it was worth a try.
 

Attachments

  • mixTest4.zip
    99.7 KB · Views: 307
  • ShortBufferLib.zip
    1.5 KB · Views: 264
Top