AudioRecorder Library V1.00

stevel05

Expert
Licensed User
Longtime User
Hmmm, Both opened for me with standard windows (8) folder archiver. Did you try v2.10 as well?
 

stevel05

Expert
Licensed User
Longtime User
I'm not sure that would be allowed. Can you download them on your phone or device.
 

Kwame Twum

Active Member
Licensed User
Longtime User
Thanks Steve, it worked. - Downloaded from my phone. (like)
 

TheWind777

Active Member
Licensed User
Longtime User
On my Nexus, under KitKat, it works perfect.

On my LG... it only works for the first recording. The second recording dies at Record.start

B4X:
Error occurred on line: 9953 (main)
java.lang.RuntimeException: start failed.


at android.media.MediaRecorder.native_start(Native Method)
at android.media.MediaRecorder.start(MediaRecorder.java:706)
at com.rootsoft.audiorecorder.AudioRecorder.start(AudioRecorder.java:227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:519)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:235)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:174)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:161)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
at android.view.View.performClick(View.java:3524)
at android.view.View$PerformClick.run(View.java:14194)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4476)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:816)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:583)
at dalvik.system.NativeStart.main(Native Method)

When I look in /sdcard/Android/data/b4a.acim/files/ it has written the filename; but it is zero-size big.

HERE IS A LINK TO THE ACTIVTY (Bigger than 512mb):

http://thewind777.angelfire.com/recorder.htm

In the Library file are the two libraries you'll need (GifDecoder and AudioRecorder)

The problem has nothing to do with the GifDecoder... because I added that afterwards.

B4X:
#Region  Project Attributes
#ApplicationLabel: B4A QuadAudioRecorder
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region

Sub process_Globals

Dim Debug As Boolean : Debug = True

' Variables Needed For Rest of Program
Dim WBNumber As String : WBNumber = "1"
Dim Underscore As String : Underscore = Chr(95)

Dim PGRecordTimer As Timer
Dim PGDelayPlayTimer As Timer
Dim PGGifTimer As Timer
Dim Frame As Int

Dim PGRecordHL As Bitmap
Dim PGRecordUP As Bitmap
Dim PGPlayON As Bitmap
Dim PGPlayOFF As Bitmap

Dim Record As AudioRecorder
Dim PlayRecording As MediaPlayer
Dim StartedRecording As Boolean : StartedRecording = False
Dim DoAudioRecorder As Boolean : DoAudioRecorder = True

Dim HILIGHT As Boolean : HILIGHT = True
Dim NOHILIGHT As Boolean : NOHILIGHT = False
Dim RecordingToggle As Boolean : RecordingToggle = NOHILIGHT
End Sub


Sub Globals

' Variables needed for "about" layout
Dim LabelProgramName, LabelVersionNumber, LabelMyName As Label
Dim ImageViewLogo As ImageView
Dim gif As GifDecoder


' Variables needed for Audio Recorder layout

Dim ButtonRTBack, ButtonRTForward, ButtonTempt As Button
Dim EditTextRTUR, EditTextRT, EditTextRTNumber, EditTextRTT As EditText
Dim LabelRTTTally As Label
Dim ButtonPlay1, ButtonPlay2, ButtonPlay3, ButtonPlay4 As Button
Dim ButtonRec1, ButtonRec2, ButtonRec3, ButtonRec4 As Button

Dim pnlRT As Panel
Dim pnlAbout As Panel
Dim WhichRecordButton As Button
Dim PlayButtons() As Button
Dim RecButtons() As Button
End Sub


Sub Activity_Create(Firsttime As Boolean)
If Firsttime Then
Record.Initialize()
PlayRecording.Initialize

PGRecordHL = LoadBitmap(File.DirAssets, "recordhl.png")
PGRecordUP = LoadBitmap(File.DirAssets, "record.png")
PGPlayON =  LoadBitmap(File.DirAssets, "playon.png")
PGPlayOFF = LoadBitmap(File.DirAssets, "playoff.png")

End If

If PGRecordTimer.IsInitialized = False Then PGRecordTimer.Initialize("PGRecordTimer",500)
If PGDelayPlayTimer.IsInitialized = False Then PGDelayPlayTimer.Initialize("DelayPlayTimer",500)

' Set-up the "Audio Recording" panel using "audiorecorder" Layout
pnlRT.Initialize("")

Activity.AddView(pnlRT,0dip,0dip,100%x,100%y)

pnlRT.LoadLayout("audiorecorder")
pnlRT.Visible=True

' Set-up the "About" panel using "about" Layout
pnlAbout.Initialize("")

Activity.AddView(pnlAbout,0dip,0dip,100%x,100%y)

pnlAbout.LoadLayout("about")
pnlAbout.Visible=False

Activity.AddMenuItem("Record/Play","RecordPlay") ' LastPanel = 7
Activity.AddMenuItem("About","about")

If PGGifTimer.IsInitialized = False Then PGGifTimer.Initialize("PGGifTimer",0)

PlayButtons = Array As Button(ButtonPlay1,ButtonPlay2,ButtonPlay3,ButtonPlay4)
RecButtons = Array As Button(ButtonRec1,ButtonRec2,ButtonRec3,ButtonRec4)


End Sub


Sub Activity_Pause
If Record.isRecording Then Record.stop

If DoAudioRecorder Then
PGRecordTimer.Enabled = False
PGDelayPlayTimer.Enabled = False
StartedRecording = False
If Record.isRecording Then Record.stop
If WhichRecordButton.IsInitialized Then WhichRecordButton.SetBackgroundImage(PGRecordUP)
End If

PGGifTimer.Enabled = False

End Sub


Sub Activity_Resume


End Sub


Sub ButtonPlay1_Click
DoSoundPlay(1)
End Sub


Sub ButtonPlay2_Click
DoSoundPlay(2)
End Sub


Sub ButtonPlay3_Click
DoSoundPlay(3)
End Sub


Sub ButtonPlay4_Click
DoSoundPlay(4)
End Sub


Sub DoSoundPlay(ANumber As Int)


Dim TheFileName As String

Dim NumberMinusOne As Int
NumberMinusOne = ANumber - 1

Dim NumberAsString As String
NumberAsString = IntToStr(ANumber)

'  If a WAV file won't play, it is likely that the original source file was not 44100Hz stereo.

If Debug Then Log(" +++ Begin of ButtonPlay1_Click")

TheFileName = "sound" & Underscore & WBNumber & Underscore & NumberAsString & ".wav"

EditTextRT.Text = "PLAYING WAV FILE /sdcard/Android/data/b4a.acim/files/" & TheFileName

StopAllRecordAndPlay("")

If Debug Then Log("ButtonRec1_Click - TheFileName = " & TheFileName)

If Record.isRecording = False Then

If File.Exists(File.DirDefaultExternal, TheFileName) Then

If Debug Then Log("ButtonPlay1_Click - PERFORMING PlayRecording.Load(File.DirDefaultExternal," & QUOTE & TheFileName & QUOTE & ")")
PlayRecording.Load(File.DirDefaultExternal, TheFileName)
If Debug Then Log("ButtonPlay1_Click - SUCCEEDED PlayRecording.Load(File.DirDefaultExternal," & QUOTE & TheFileName & QUOTE & ")")

PGDelayPlayTimer.Enabled = True ' Play in 500 ms

Else
Msgbox("Record an Audio File first by clicking on the red circle","WARNING")
End If
Else
ToastMessageShow("STILL RECORDING, Stop Recording first.",False)
End If

If Debug Then Log(" --- End of ButtonPlay1_Click")
If Debug Then Log(" ")
End Sub


Sub DelayPlayTimer_tick
If Debug Then Log(" +++ Begin of DelayPlayTimer_tick")

PGDelayPlayTimer.Enabled = False
PlayRecording.Play

If Debug Then Log(" --- End of DelayPlayTimer_tick")
If Debug Then Log(" ")
End Sub


Sub ButtonRec1_Click
DoSoundRecord(1)
End Sub


Sub ButtonRec2_Click
DoSoundRecord(2)
End Sub


Sub ButtonRec3_Click
DoSoundRecord(3)
End Sub


Sub ButtonRec4_Click
DoSoundRecord(4)
End Sub


Sub DoSoundRecord(ANumber As Int)

Dim TheFileName As String
Dim NumberAsString As String
Dim NumberMinusOne As Int
NumberMinusOne = ANumber - 1

NumberAsString = IntToStr(ANumber)

WhichRecordButton = RecButtons(NumberMinusOne)

If Debug Then Log(" +++ Begin of ButtonRec1_Click")

TheFileName = "sound" & Underscore & WBNumber & Underscore & NumberAsString & ".wav"
If Debug Then Log("ButtonRec1_Click - TheFileName = " & TheFileName)

EditTextRT.Text = "RECORDING WAV FILE /sdcard/Android/data/b4a.acim/files/" & TheFileName

If PlayRecording.IsPlaying Then PlayRecording.Pause

If StartedRecording Then
' Turn-off Recording Timer

ToastMessageShow("STOPPED Recording",False)
PGRecordTimer.Enabled = False

If Debug Then Log("ButtonRec1_Click - PERFORMING Record.Stop")

If Record.isRecording Then
Record.Stop
End If

If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.Stop")

StartedRecording = False
WhichRecordButton.SetBackgroundImage(PGRecordUP)

StopAllRecordAndPlay("")
RefreshRecordPlayImages("")

Else
' Turn-on Recording Timer

PrepareRecorder(TheFileName)

If Record.isRecording = False Then

If Debug Then Log("ButtonRec1_Click - PERFORMING Record.Start")
Record.Start
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.Start")

ToastMessageShow("STARTED Recording",False)
StartedRecording = True
Else
If Debug Then Log("ButtonRec1_Click - WHOOPS, TRYING TO START RECORDING WHEN STILL RECORDING")
End If

PGRecordTimer.Enabled = True
End If

If Debug Then Log(" --- End of ButtonRec1_Click")
If Debug Then Log(" ")
End Sub


Sub PrepareRecorder(FileName As String)
If Debug Then Log(" +++ Begin of PrepareRecorder()")
Dim NumSeconds As Int

Record.AudioSource = Record.AS_MIC
Record.OutputFormat = Record.OF_THREE_GPP


Record.AudioEncoder = Record.AE_AMR_NB  ' AudioCodecAMRAdaptive Multi-Rate narrowband audio codec, also known as AMR OR AMR-NB
'Record.AudioEncoder = Record.AE_AAC  ' it seems like Android doesn't natively support streaming of AAC files.
'Record.AudioEncoder = Record.AE_AMR_WB ' wouldn't load

' 2 Min = 120
' 4 Min = 240
' 5 Min = 300
' 7 Min = 420
' 10 Min = 600

NumSeconds = 300 ' 5 Minutes
Record.MaxDuration = NumSeconds * 1000 ' in ms
Record.AudioEncodingBitRate = 44100

' On the Nexus, the directory it writes to with DirDefaultExternal is:
' /sdcard/Android/data/b4a.acim/files/

If Debug Then Log("ButtonRec1_Click - PERFORMING Record.setOutputFile")
Record.setOutputFile(File.DirDefaultExternal,FileName)
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.setOutputFile")

If Debug Then Log("ButtonRec1_Click - PERFORMING Record.prepare()")
Record.Prepare()
If Debug Then Log("ButtonRec1_Click - SUCCEEDED Record.prepare()")

If Debug Then Log(" --- End of PrepareRecorder()")
If Debug Then Log(" ")
End Sub


Sub PGRecordTimer_tick
If Debug Then Log(" +++ Begin of PGRecordTimer_tick")

Dim WhichImage As Bitmap
If DoAudioRecorder Then
If Record.isRecording Then
If RecordingToggle = NOHILIGHT Then
RecordingToggle = HILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordHL)
If Debug Then Log("PGRecordTimer_tick - HILIGHT Image")
Else
RecordingToggle = NOHILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordUP)
If Debug Then Log("PGRecordTimer_tick - NOHILIGHT Image")

RefreshRecordPlayImages("")
End If
End If
Else
RecordingToggle = NOHILIGHT
WhichRecordButton.SetBackgroundImage(PGRecordUP)
If Debug Then Log("PGRecordTimer_tick - DoAudioRecorder = FALSE... NOHILIGHT Image")
End If

If Debug Then Log(" --- End of PGRecordTimer_tick")
If Debug Then Log(" ")
End Sub


Sub IntToStr(TheNumber As Int) As String
  ' Convert Int to String

   Dim ReturnString As String
   ReturnString = TheNumber

   Return ReturnString
End Sub


Sub ButtonRTDelete_Click
If DoAudioRecorder Then
If Debug Then Log(" +++ Begin ButtonRTDelete_Click")

AskThenDeleteFourRecordings("")

EditTextRT.Text = ""

End If
End Sub



Sub AskThenDeleteFourRecordings(BlankString As String)
Dim TheFileName As String
Dim z As Int
Dim Count As Int : Count = 0
Dim DeleteFour As Int
Dim Icon As Bitmap
Dim PositiveResponse As Int
Dim Success As Boolean
Dim RecordingWord As String

Icon = LoadBitmap(File.DirAssets, "msgboxicon.png")

For z = 1 To 4
TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"

If File.Exists(File.DirDefaultExternal,TheFileName) Then
Count = Count + 1
End If
Next

If Count = 1 Then
RecordingWord = "Recording"
Else
RecordingWord = "Recordings"
End If

If Count <> 0 Then
DeleteFour = Msgbox2("Do you wish to delete the " & IntToStr(Count) & " Audio " & RecordingWord & "? You can not reverse this process.","DELETING AUDIO FILES","YES","","NO",Icon)
End If

PositiveResponse = DialogResponse.POSITIVE

';

If DeleteFour = PositiveResponse Then
For z = 1 To 4
TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"

If File.Exists(File.DirDefaultExternal,TheFileName) Then
Success = File.Delete(File.DirDefaultExternal, TheFileName)
End If
Next
End If

RefreshRecordPlayImages("")
End Sub


Sub RefreshRecordPlayImages(BlankString As String)
Dim z As Int
Dim zm1 As Int

Dim TheFileName As String

If Debug Then Log(" +++ Begin of StopAllRecordAndPlay()")

For z = 1 To 4
zm1 = z - 1

If RecButtons(zm1).IsInitialized Then
RecButtons(zm1).SetBackgroundImage(PGRecordUP)
Else
If Debug Then Log("RefreshRecordPlayImages() - RecButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If

TheFileName = "sound" & Underscore & WBNumber & Underscore & IntToStr(z) & ".wav"
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName)

If File.Exists(File.DirDefaultExternal, TheFileName) Then
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName & " EXISTS")

' Put PGPlayON into Button
If PlayButtons(zm1).IsInitialized Then
PlayButtons(zm1).SetBackgroundImage(PGPlayON)
Else
If Debug Then Log("RefreshRecordPlayImages() - PlayButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If
Else
If Debug Then Log("RefreshRecordPlayImages() - TheFileName = " & TheFileName & " DOES NOT EXIST")

' Put PGPlayOFF into Button
If PlayButtons(zm1).IsInitialized Then
PlayButtons(zm1).SetBackgroundImage(PGPlayOFF)
Else
If Debug Then Log("RefreshRecordPlayImages() - PlayButtons(" & IntToStr(zm1) & ") WASN'T INITIALIZED")
End If

End If
Next

If Debug Then Log(" --- End of StopAllRecordAndPlay()")
If Debug Then Log(" ")
End Sub


Sub StopAllRecordAndPlay(BlankString As String)
If Debug Then Log(" +++ Begin of StopAllRecordAndPlay()")

If PGDelayPlayTimer.IsInitialized Then PGDelayPlayTimer.Enabled = False
If PGDelayPlayTimer.IsInitialized Then PGDelayPlayTimer.Enabled = False

If PlayRecording.IsPlaying Then
PlayRecording.Pause
ToastMessageShow("STOPPED Playing",False)
End If

If Record.isRecording Then
Record.stop
ToastMessageShow("STOPPED Recording",False)
End If

If Debug Then Log(" --- End of StopAllRecordAndPlay()")
If Debug Then Log(" ")
End Sub


Sub ButtonRTBack_Click

Dim TheNumber As Int

TheNumber = StrToInt(WBNumber)

TheNumber = TheNumber - 1

If TheNumber < 0 Then TheNumber = 0

WBNumber = IntToStr(TheNumber)
EditTextRTNumber.Text = WBNumber
End Sub


Sub ButtonRTForward_Click
Dim TheNumber As Int

TheNumber = StrToInt(WBNumber)

TheNumber = TheNumber + 1

If TheNumber < 0 Then TheNumber = 0

WBNumber = IntToStr(TheNumber)
EditTextRTNumber.Text = WBNumber
End Sub


Sub StrToInt(TheString As String) As Int
' Convert String to Number

   Dim ReturnVal As Int

If TheString = "" OR TheString = Null Then TheString = "0"
   ReturnVal = TheString
   Return ReturnVal
End Sub


Sub RecordPlay_click
pnlRT.Visible=True
pnlAbout.Visible=False
End Sub


Sub About_click
StopAllRecordAndPlay("")
pnlRT.Visible=False
pnlAbout.Visible=True

gif.DisposeFrames
gif.Load(File.DirAssets, "dino.gif")
Frame = 0
PGGifTimer.Interval = gif.Delay(Frame)
ImageViewLogo.Bitmap = gif.Frame(Frame)
'ImageViewLogo.Gravity = Gravity.FILL
PGGifTimer.Enabled = True
End Sub


Sub ButtonAboutMenu_Click
Activity.OpenMenu
End Sub


Sub ButtonRTMenu_Click
' Turn off About Animation

If PGGifTimer.IsInitialized = True Then PGGifTimer.Enabled = False
Activity.OpenMenu
End Sub


Sub PGGifTimer_Tick
PGGifTimer.Enabled = False
Frame = Frame + 1
If Frame >= gif.FrameCount Then
Frame = 0
End If
PGGifTimer.Interval = gif.Delay(Frame)
ImageViewLogo.Bitmap = gif.Frame(Frame)
PGGifTimer.Enabled = True
End Sub
This is extracted from a huge program... so the problem exhibited itself with the huge program, as well.

It will seem to work fine on many phones, such as my Nexus.

Some kind of memory problem, maybe?

I have a 32 GB SD Card... but system memory is 288.25 used, 102.05 free (as reported by Memory Cleaner). 236 MB free after cleaning.

So, probably not a memory problem.

To use the recorder... click on one of the four sound recorder buttons. It will blink orange as it records it. Then click the blinking orange button to stop the recording. Click the green play button to the left of it to hear it.

You can record another set of four each time you click the forward or backward button (to infinity).

However, with my LG Optiumus Extreme L40G under Android 4.0.3, it crashes the second time you try to record. Works fine on my Nexus.

Version Number of the Library: AudioRecorder 2.1.0

====================

Two other people have commented about the same problem.

This library only seems to work the first time you use it. The second time, it crashes with a 'failed to start'.

I tried putting a 500 ms - 1000 ms delay between prepare and start... no difference.

This problem seems to be there for any Android 4.0 and before. I've tried it on 2.3 and 4.0 and both does same thing.

If we had the Reset() and Release() functions, might be able to do a work-around.

Tried re-initializing the Recorder again, then loading up the parameters, then preparing, then starting. Same thing.

Since there is only one MediaRecorder instance on the Android (possibly?)... might it be possible to call mRecorder.reset or mRecorder.release using some different library to release it?

..

Every place out on the internet that reports this error says it is related to not doing a mRecorder.release() and/or an mRecorder.reset() after the mRecorder.stop() is done (inside the class, which is inside the .jar file as a compiled binary; so WE can't control that).

So, he needs to do it the right way.

Since this was only a problem that seems to bug Android v4.0 and before, most aren't seeing the problem.

If the Library had the release() and reset() functions built-in to the library, we could do it ourselves. For the life of me, I can't think of a way to get at the instance after the .stop has already occurred. Anybody???
 
Last edited:

shaxboz

Member
Licensed User
Longtime User
Is it possible to get AudioMaxAmplitude without starting record? I want to start record when AudioMaxAmplitude>4000 and stop recording when AudioMaxAmplitude<4000.
 

shaxboz

Member
Licensed User
Longtime User
Why this library not writing, wave format? To write wave file, what encoder and auioformat should I write to code?
 

Kwame Twum

Active Member
Licensed User
Longtime User
EDIT: Note: if you want to hear the captured sound, it's best to use quicktime player cause i think it's the only one who is possible to decode it. (According to what encode you use.)
Does this mean the Android decoders can't play them?
 

borofan

Member
Licensed User
Longtime User
great library, is there a pause function to temporarily stop recording and then resume again?
 

DonManfred

Expert
Licensed User
Longtime User
This thread is in the "old libraries archive".
The author is no more active here in forum and the development has stopped. You won´t get support anymore.
 
Top