Android Question AudioStreamer File Location Problem (Solved)

omo

Active Member
Licensed User
Longtime User
I use AudioStreamer library as audio recorder; It records fine and when i click on playback button, it plays fine; once the record activity module is still at foreground. I wanted to copy the recorded .wav audio to another directory so i can rename it, but is like the actual audio file never existed. Playback gets file from Pool.Load(SourceDir,SourceFileName), but destination audio file never existed in such directory:
File.MakeDir(rp.GetSafeDirDefaultExternal(""),"myprojaudio") SourceDir = rp.GetSafeDirDefaultExternal("myprojaudio") Dim SourceFileName As String = "yourfilename.wav" 'The file you wish to use PoolID = Pool.Load(SourceDir,SourceFileName)

How can i get actual audio that i can copy, rename and listed for future playback?
Sub PlayRecording
Dim ret As Int 'Used in call to Pool.Play. ret = 0 if error occurs
Dim PoolID As Int 'Identifies the Pool number when a sound file is loaded
'File.DirDefaultExternal 'or the Directory where your file is located
File.MakeDir(rp.GetSafeDirDefaultExternal(""),"myprojaudio")
SourceDir = rp.GetSafeDirDefaultExternal("myprojaudio")

Dim SourceFileName As String = "yourfilename.wav" 'The file you wish to use

PoolID = Pool.Load(SourceDir,SourceFileName) 'Loads the file and gets it's number in the pool.
MsgboxAsync("SourceDir =" & SourceDir, SourceFileName)
Sleep(100) 'Some delay required between pool loading and playback - I'm unsure why or how much?

'Play the sound
'ret = Pool.Play(PoolID,VolumeLeft,VolumeRight,Priority,Loop,Pitch)
ret = Pool.Play(PoolID,1,1,1,0,1)

End Sub

Sub Btnrecord_Click
Movie1.Paused = False
buffers.Clear
streamer.StartRecording
recordingStart = DateTime.Now
timer1.Enabled = True
Timer1_Tick

LbClock.Text = "RECORDING..."
LbClock.TextSize = "35"
BtnPlayback.Enabled = False


End Sub

Sub streamer_RecordBuffer (Buffer() As Byte)
'collect the recording data
buffers.Add(Buffer)
End Sub
 
Last edited:

JohnC

Expert
Licensed User
Longtime User
I don't see the code where you are trying to copy the file elsewhere.

Also how are you determining "but destination audio file never existed in such directory"?
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
I don't see the code where you are trying to copy the file elsewhere.

Also how are you determining "but destination audio file never existed in such directory"?
Thank you @JohnC, let me put entire relevant code module here as shown below. I was trying to copy the audio file under Sub streamer_PlaybackComplete. Why? Just because i do not know where the actual audio file got created while recording with streamer.startrecording; but one thing that was sure was that after recording it got played back from PoolID = Pool.Load(SourceDir,SourceFileName) under Sub PlayRecording (i only assumed because i don't know if it actually exists). Due to this assumption, i tried to copy the file immediately after audio playback is completed, but to my surprise no such file existed in destination.

More Detail Code Here:
#Region  Project Attributes
    #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 rp As RuntimePermissions
    Public SourceDir As String
    
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private BtnStop As B4XView
    Private BtnPlayback As B4XView
    Private BtnPlay As B4XView
    Private LbInfo As Label
    Private LbClock As B4XView
    Private Prec As B4XView
    Private lblC As Label
    'Requires Audio library
    Private Pool As SoundPool
    
End Sub


Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission!", True)
        'Return
    End If
    
    
    Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_RECORD_AUDIO)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission!", True)
        'Return
    End If
    
    Activity.LoadLayout("vrecorder2")
    If FirstTime Then
        streamer.Initialize("streamer", 44100, True, 16, streamer.VOLUME_MUSIC)
        buffers.Initialize
        timer1.Initialize("timer1", 1000)
        
    End If
    
    BtnPlayback.Enabled = False
    
    Pool.Initialize(1)
End Sub

Sub streamer_RecordBuffer (Buffer() As Byte)
    'collect the recording data
    buffers.Add(Buffer)
End Sub

Sub Timer1_Tick
    LbClock.Text = "Recording..."
End Sub

Sub Activity_Resume

End Sub

Sub BtnStop_Click
    streamer.StopRecording
    timer1.Enabled = False
    BtnPlayback.Enabled = True
    LbClock.Text = "STOPPED"
    
End Sub

Sub BtnPlayback_Click
    ''playback here
    BtnStop.Enabled = True
    BtnPlay.Enabled = False
    streamer.StartPlaying
    For Each b() As Byte In buffers
        streamer.Write(b)
    Next
    PlayRecording
    streamer.Write(Null)
    LbClock.Text = "PLAYING BACK..."
        
End Sub

Sub streamer_PlaybackComplete
    Log("PlaybackComplete")
    BtnStop_Click
    LbClock.Text = "FINISHED PLAYING"
    Dim fd As InputDialog ' FileDialog
    fd.Hint = "Save my recorded project audio from my supervisor or discussion?"
    fd.HintColor = Colors.ARGB(255, 0, 0, 0)
    
    Dim sf As Object = fd.ShowAsync("","Do you want to save or discard your recorded audio?", "OK","", "Cancel", Null, False)
    Wait For (sf) Dialog_Result(Result As Int)
    If Result = DialogResponse.POSITIVE Then
      Log(fd.Input)
        Dim file2 As String = fd.Input & ".wav"
        MsgboxAsync("fd.input =" & file2, "test1")
        ToastMessageShow("fd.input =" & file2, True)
        SourceDir  = rp.GetSafeDirDefaultExternal("myprojaudio")
        File.Copy(SourceDir, "yourfilename.wav", File.DirInternal,fd.Input & ".wav")
       If File.Exists(File.DirInternal,fd.Input & ".wav") Then
            MsgboxAsync("fd.input =" & file2, "test2 exist")
        'ToastMessageShow("fd.input =" & fd.Input, True)
       End If   
        
        Starter.sql1.Initialize(File.DirInternal, "proj.db", False) 'DirInternal
        Starter.sql1.ExecNonQuery2("INSERT INTO aulink(fname)VALUES(?)", Array As Object (file2))
    
        ToastMessageShow("Your Audio saved as:" & file2, True)
        Starter.sql1.Close
            
    else if Result = DialogResponse.NEGATIVE Then
        StartActivity(audioview)
    
    End If

End Sub

Sub BtnRecording_Click
      buffers.Clear
    streamer.StartRecording
    recordingStart = DateTime.Now
    timer1.Enabled = True
    Timer1_Tick
    
    LbClock.Text = "RECORDING..."
    LbClock.TextSize = "35"
    BtnPlayback.Enabled = False
End Sub

Sub Activity_Click
    
End Sub

Sub PlayRecording
    Dim ret As Int 'Used in call to Pool.Play. ret = 0 if error occurs
    Dim PoolID As Int 'Identifies the Pool number when a sound file is loaded
    File.MakeDir(rp.GetSafeDirDefaultExternal(""),"myprojaudio")
    SourceDir  = rp.GetSafeDirDefaultExternal("myprojaudio")
    
    Dim SourceFileName As String = "yourfilename.wav" 'The file you wish to use
    'Load the sound
    PoolID = Pool.Load(SourceDir,SourceFileName) 'Loads the file and gets it's number in the pool.
    MsgboxAsync("SourceDir =" & SourceDir, SourceFileName)
    Sleep(100) 'Some delay required between pool loading and playback - I'm unsure why or how much?

    'Play the sound
    'ret = Pool.Play(PoolID,VolumeLeft,VolumeRight,Priority,Loop,Pitch)
   ret = Pool.Play(PoolID,1,1,1,0,1)
   
End Sub
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Try adding rp.PERMISSION_READ_EXTERNAL_STORAGE runtime permission to your app.

You are properly asking for write permission and that's why it can record the file ok to the GetSafeDirDefaultExternal directory.

But maybe the reason why you can't copy the file is because you need the read permission to fetch the recording from the "GetSafeDirDefaultExternal" directory.
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Try adding rp.PERMISSION_READ_EXTERNAL_STORAGE runtime permission to your app.

You are properly asking for write permission and that's why it can record the file ok to the GetSafeDirDefaultExternal directory.

But maybe the reason why you can't copy the file is because you need the read permission to fetch the recording from the "GetSafeDirDefaultExternal" directory.
Yes, i thought the same initially, i first included read permission, but i later removed it when i discovered that it was not listed as dangerous permission under list permission, i removed it from manifest and runtime declaration. Although, i tried to include it again now, but still no audio file. The folder was created, but no audio file was copied or found inside
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Ok, first lets just make sure we are on the same page...

1) After the recording (but before the playback/copy attempt), do you see the file in the GetSafeDirDefaultExternal directory (using a file explorer app)?

2) If you do see the file, then is there any error in the log listing (right side of IDE) when you execute this line:

B4X:
File.Copy(SourceDir, "yourfilename.wav", File.DirInternal,fd.Input & ".wav")
 
Last edited:
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Some other issues I see:

1) When the playback is complete, you call BtnStop_Click, but that only stops the recording.
2) Maybe try using different streaming objects - one for record and one for playback.
3) Make sure to close each streaming object when done using it (streamingxx.Close) - maybe because you are not closing the streaming object, it is preventing the file from being copied.
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Ok, first lets just make sure we are on the same page...

1) After the recording (but before the playback/copy attempt), do you see the file in the GetSafeDirDefaultExternal directory?

2) If you do see the file, then is there any error in the log listing (right side of IDE) when you execute this line:

B4X:
File.Copy(SourceDir, "yourfilename.wav", File.DirInternal,fd.Input & ".wav")

1). No! That was exact cause of confusion. Recording was only using: streamer.StartRecording in AudioStreamer library, there was no other parameter that demanded "destination directory", so i don't actually know default recording destination. This is exact reason why i went back to streamer_playbackcomplete to find out where it was playing from as "yourfilename.wav". But is like, filename and sourcedir are just dummies, because i now discovered is recording to buffer with this:
Sub streamer_RecordBuffer (Buffer() As Byte) 'collect the recording data buffers.Add(Buffer) End Sub

while is reading/playback from buffer with this code especially where i indicated below:
Sub BtnPlayback_Click ''playback here BtnStop.Enabled = True BtnPlay.Enabled = False streamer.StartPlaying '............................................................................from here For Each b() As Byte In buffers streamer.Write(b) Next PlayRecording '..............................................................................to here streamer.Write(Null) LbClock.Text = "PLAYING BACK..." End Sub
Question now is that how can i get audio.wav file from buffer now ?

2. No log error, (though i use emulator to some extent before running it on phone) everything usually runs fine, except that i couldn't locate audio file when run on device
 
Last edited:
Upvote 0

JohnC

Expert
Licensed User
Longtime User
OK, now I understand what page you are on.

You need to properly save the buffer to disk in the "WAV" format.

This discusses the streaming object, which looks like you might have based you code on:


But then look at this post in that thread that has sample code to save in WAV format:

 
  • Like
Reactions: omo
Upvote 0

omo

Active Member
Licensed User
Longtime User
Some other issues I see:

1) When the playback is complete, you call BtnStop_Click, but that only stops the recording.
2) Maybe try using different streaming objects - one for record and one for playback.
3) Make sure to close each streaming object when done using it (streamingxx.Close) - maybe because you are not closing the streaming object, it is preventing the file from being copied.

1. Before calling BtnStop_Click, recording has finished then and once playback finished playing, it fires BtnStop_Click, it doesn't affect recording and playback
2. But since recording and playback have no issue, do you think different streaming object will solve problem in this case? We will still end up looking for audio destination directory.
3. I will try this and see
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
OK, now I understand what page you are on.

You need to properly save the buffer to disk in the "WAV" format.

This discusses the streaming object, which looks like you might have based you code on:


But then look at this post in that thread that has sample code to save in WAV format:

Whaoo! Thank you, you safe my day. Exactly what I need, I am sure it will work. I will have to save buffer bytes to audio file. Thank you! I didn't sleep throughout night, now is 5:02am here. Regards
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Whaoo! Thank you, you safe my day. Exactly what I need, I am sure it will work. I will have to save buffer bytes to audio file. Thank you! I didn't sleep throughout night, now is 5:02am here. Regards
@johnC said:
But then look at this post in that thread that has sample code to save in WAV format:


Thank you once again, @JohnC, this your second suggestion solved my problem as i predicted it would solve.It did, thank you![/QUOTE]
 
Upvote 0
Top