Android Question Wav recorder problem on API 33

Spright

Active Member
I'm really trying to understand why this WAV recorder introduces an error on API 33, but I can't figure out what I'm doing wrong.
The last version that I know it works is Android Pie.

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #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
    ' These global variables will be declared once when the application starts.
    ' These variables can be accessed from all modules.
    Private streamer As AudioStreamer
    Private buffers As List
    Private timer1 As Timer
    Private recordingStart As Long
    Private output As OutputStream
    Private recording As Boolean
    Private mBitRate As Int = 16
    Private mSampleRate As Int = 22050
    Private mMono As Boolean = True
    Private mFileName As String = "1.wav"
    Private mp As MediaPlayer
End Sub

Sub Globals
    Dim Label1 As Label
    Dim btnPlay As Button
    Dim btnStartRecording As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    If FirstTime Then
        streamer.Initialize("streamer", mSampleRate, mMono, mBitRate, streamer.VOLUME_MUSIC)
        buffers.Initialize
        timer1.Initialize("timer1", 1000)
        mp.Initialize2("mp")
    End If
End Sub

Sub StartWaveFile(Dir As String, FileName As String, SampleRate As Int, Mono As Boolean _
        , BitsPerSample As Int) As OutputStream
    ' File.Delete(Dir, FileName)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteBytes("RIFF".GetBytes("ASCII"), 0, 4, raf.CurrentPosition)
    raf.CurrentPosition = 8 'skip 4 bytes for the size
    raf.WriteBytes("WAVE".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteBytes("fmt ".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(16, raf.CurrentPosition)
    raf.WriteShort(1, raf.CurrentPosition)
    Dim numberOfChannels As Int
    If Mono Then numberOfChannels = 1 Else numberOfChannels = 2
    raf.WriteShort(numberOfChannels, raf.CurrentPosition)
    raf.WriteInt(SampleRate, raf.CurrentPosition)
    raf.WriteInt(SampleRate * numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(BitsPerSample, raf.CurrentPosition)
    raf.WriteBytes("data".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(0, raf.CurrentPosition)
    raf.Close
    Return File.OpenOutput(Dir, FileName, True)
End Sub

Sub CloseWaveFile(Dir As String, FileName As String)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteInt(raf.Size - 8, 4)
    raf.WriteInt(raf.Size - 44, 40)
    raf.Close
End Sub

Sub streamer_RecordBuffer (Buffer() As Byte)
    If recording Then output.WriteBytes(Buffer, 0, Buffer.Length)
    ' The above check is required as the last message will arrive after we call StopRecording.
End Sub
 
Sub btnStartRecording_Click
    buffers.Clear
    output = StartWaveFile(File.DirInternal, mFileName, mSampleRate, mMono, mBitRate)
    recording = True
    streamer.StartRecording
    recordingStart = DateTime.Now
    timer1.Enabled = True
    Timer1_Tick
    btnPlay.Enabled = False
End Sub

Sub Timer1_Tick
    Label1.Text = "Recording: " & _
        Round((DateTime.Now - recordingStart) / DateTime.TicksPerSecond) & " seconds"
End Sub

Sub btnStopRecording_Click
    streamer.StopRecording
    recording = False
    output.Close
    CloseWaveFile(File.DirInternal, mFileName)
    timer1.Enabled = False
    btnPlay.Enabled = True
    Label1.Text = ""
End Sub

Sub btnPlay_Click
    mp.Load(File.DirInternal, mFileName)
    mp.Play
End Sub
Sub mp_Complete
    Log("PlaybackComplete")
    btnStartRecording.Enabled = True
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Error log
Error log:
Logger connected to: RZCW71WVQ3M
--------- beginning of main
** Activity (main) Create (first time) **
** Activity (main) Resume **
** Activity (main) Resume **
main_startwavefile (java line: 519)
java.io.FileNotFoundException: /storage/emulated/0/1.wav: open failed: EPERM (Operation not permitted)
    at libcore.io.IoBridge.open(IoBridge.java:574)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:289)
    at anywheresoftware.b4a.randomaccessfile.RandomAccessFile.Initialize2(RandomAccessFile.java:103)
    at b4a.example.main._startwavefile(main.java:519)
    at b4a.example.main._btnstartrecording_click(main.java:400)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)
    at libcore.io.Linux.open(Native Method)
    at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
    at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
    at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8756)
    at libcore.io.IoBridge.open(IoBridge.java:560)
    ... 22 more
java.io.FileNotFoundException: /storage/emulated/0/1.wav: open failed: EPERM (Operation not permitted)
** Activity (main) Create (first time) **
** Activity (main) Resume **
main_btnstartrecording_click (java line: 404)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1581)
    at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
    at b4a.example.main._btnstartrecording_click(main.java:404)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
** Activity (main) Create (first time) **
** Activity (main) Resume **
main_btnstartrecording_click (java line: 404)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1581)
    at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
    at b4a.example.main._btnstartrecording_click(main.java:404)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
** Activity (main) Create (first time) **
** Activity (main) Resume **
main_btnstartrecording_click (java line: 404)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1581)
    at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
    at b4a.example.main._btnstartrecording_click(main.java:404)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
** Activity (main) Create (first time) **
** Activity (main) Resume **
** Activity (main) Resume **
main_btnstartrecording_click (java line: 404)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1581)
    at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
    at b4a.example.main._btnstartrecording_click(main.java:404)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
** Activity (main) Create (first time) **
** Activity (main) Resume **
main_btnstartrecording_click (java line: 404)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1581)
    at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
    at b4a.example.main._btnstartrecording_click(main.java:404)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8043)
    at android.widget.TextView.performClick(TextView.java:17816)
    at android.view.View.performClickInternal(View.java:8020)
    at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
    at android.view.View$PerformClick.run(View.java:31850)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
 

Attachments

  • RecordToWaveFile.zip
    4.6 KB · Views: 27

JohnC

Expert
Licensed User
Longtime User
The error contains the filespec "/storage/emulated/0/1.wav", so it looks like you are trying to save a recording in the root of the internal storage, which later versions of Android limit an apps ability to access that area of storage.

These workarounds may help:


 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
to save a recording in the root of the internal storage
he posted the code
B4X:
 output = StartWaveFile(File.DirInternal, mFileName, mSampleRate, mMono, mBitRate)

it points to File.DirInternal, not File.DirRootExternal

but i agree that the error seems to be related to another path.
 
Upvote 0

Spright

Active Member
I use File.DirInternal only , it should not need manifest nor runtime permission to use. It's strange to see that path in the error message as I'm not using any external storage at all.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've tried to run your project but you are not requesting the audio permission so it crashes:

Error occurred on line: 89 (Main)
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
at android.media.AudioRecord.startRecording(AudioRecord.java:1499)
at anywheresoftware.b4a.audio.AudioStreamer.StartRecording(AudioStreamer.java:98)
at b4a.example.main._btnstartrecording_click(main.java:473)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:205)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:7659)
at android.view.View.performClickInternal(View.java:7636)
at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
at android.view.View$PerformClick.run(View.java:30156)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

You should also switch to B4XPages or the recording will break when the activity is paused.
 
Upvote 0

Spright

Active Member
Thanks for the help, here's the final code. Cleaned up to work on all Androids. I Stillhave to create a B4XPage version later.
B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #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
    ' These global variables will be declared once when the application starts.
    ' These variables can be accessed from all modules.
    Private streamer As AudioStreamer
    Private buffers As List
    Private timer1 As Timer
    Private recordingStart As Long
    Private output As OutputStream
    Private recording As Boolean
    Private mBitRate As Int = 16
    Private mSampleRate As Int = 22050
    Private mMono As Boolean = True
    Private mFileName As String = "1.wav"
    Private mp As MediaPlayer
    Private rp As RuntimePermissions
End Sub

Sub Globals
    Dim Label1 As Label
    Dim btnPlay As Button
    Dim btnStartRecording As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    
    rp.checkandRequest(rp.PERMISSION_RECORD_AUDIO)
    wait for Activity_PermissionResult(Permission As String,  Result As Boolean)
    If Result = False Then
        MsgboxAsync("To continue you have to accept the Permission.", "Warning")
        Return ' User denied permission (Doublecheck if okay to return Create)
    End If
    
    Activity.LoadLayout("1")   

    If FirstTime Then
        streamer.Initialize("streamer", mSampleRate, mMono, mBitRate, streamer.VOLUME_MUSIC)
        buffers.Initialize
        timer1.Initialize("timer1", 1000)
        mp.Initialize2("mp")
    End If
End Sub

Sub StartWaveFile(Dir As String, FileName As String, SampleRate As Int, Mono As Boolean _
        , BitsPerSample As Int) As OutputStream
    File.Delete(Dir, FileName)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteBytes("RIFF".GetBytes("ASCII"), 0, 4, raf.CurrentPosition)
    raf.CurrentPosition = 8 'skip 4 bytes for the size
    raf.WriteBytes("WAVE".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteBytes("fmt ".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(16, raf.CurrentPosition)
    raf.WriteShort(1, raf.CurrentPosition)
    Dim numberOfChannels As Int
    If Mono Then numberOfChannels = 1 Else numberOfChannels = 2
    raf.WriteShort(numberOfChannels, raf.CurrentPosition)
    raf.WriteInt(SampleRate, raf.CurrentPosition)
    raf.WriteInt(SampleRate * numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
    raf.WriteShort(BitsPerSample, raf.CurrentPosition)
    raf.WriteBytes("data".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
    raf.WriteInt(0, raf.CurrentPosition)
    raf.Close
    Return File.OpenOutput(Dir, FileName, True)
End Sub

Sub CloseWaveFile(Dir As String, FileName As String)
    Dim raf As RandomAccessFile
    raf.Initialize2(Dir, FileName, False, True)
    raf.WriteInt(raf.Size - 8, 4)
    raf.WriteInt(raf.Size - 44, 40)
    raf.Close
End Sub

Sub streamer_RecordBuffer (Buffer() As Byte)
    If recording Then output.WriteBytes(Buffer, 0, Buffer.Length)
    ' The above check is required as the last message will arrive after we call StopRecording.
End Sub
 
Sub btnStartRecording_Click
    buffers.Clear
    output = StartWaveFile(File.DirInternal, mFileName, mSampleRate, mMono, mBitRate)
    recording = True
    streamer.StartRecording
    recordingStart = DateTime.Now
    timer1.Enabled = True
    Timer1_Tick
    btnPlay.Enabled = False
End Sub

Sub Timer1_Tick
    Label1.Text = "Recording: " & _
        Round((DateTime.Now - recordingStart) / DateTime.TicksPerSecond) & " seconds"
End Sub

Sub btnStopRecording_Click
    streamer.StopRecording
    recording = False
    output.Close
    CloseWaveFile(File.DirInternal, mFileName)
    timer1.Enabled = False
    btnPlay.Enabled = True
    Label1.Text = ""
End Sub

Sub btnPlay_Click
    mp.Load(File.DirInternal, mFileName)
    mp.Play
End Sub
Sub mp_Complete
    Log("PlaybackComplete")
    btnStartRecording.Enabled = True
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub
 

Attachments

  • RecordToWaveFile.zip
    3.7 KB · Views: 29
Upvote 0

JohnC

Expert
Licensed User
Longtime User
I use File.DirInternal only , it should not need manifest nor runtime permission to use. It's strange to see that path in the error message as I'm not using any external storage at all.
Try doing a search of your source for "1.wav" and see if there is a hit.
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
In #1 is the filename in this variable
B4X:
Private mFileName As String = "1.wav"
Doh! Missed that - very strange that it seems to be defaulting to rootexternal for the file.
 
Upvote 0
Top