Android Question "Rewind" function of audiostreamer

Olivier Zeegers

Active Member
Licensed User
Hello Erel,

I have found the documentation of Audiostreamer in this link: https://www.b4x.com/android/help/audio.html#audiostreamer

I can understand that one can start a recording and later on play it back but I don't see any function to start playing back from a certain position in the stream ?
Like i asked, I want to build an app that mimics a dictaphone, a sort of voice recorder. But the user should be able to press the record button and record his voice and then if he made a mistake pus the rewind button to rewind a little and then either OVERWRITE his previous recording of INSERT a new voice recording.

I try to make a better version of the app dictate + connect: http://www.dictate-connect.com/?page_id=134

You said this was possible in your previous answer to my question, so I bought B4A and B4I, but I don't see how ?

thank you
 

Olivier Zeegers

Active Member
Licensed User
Hello Steve,

Thank you for your support..

Is this correct:

To achieve the voice recording with rewind possibility I have to do the following:

- start recording using AudioRecord to a buffer in memory
- when the user presses "Rewind" button I stop AudioRecord, and let AudioTrack play the buffer while I use SetPlaybackHeadPosition to a few seconds earlier.

But how do I get the recorded audio buffer from AudioRecord into AudioTrack ?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
You would just read the data from the same buffer, I would suggest that when the user presses rewind, you store the new recording position relative to the recorded buffer and when they start recording again, you record into a different buffer and splice them together afterwards.
 
Upvote 0

Olivier Zeegers

Active Member
Licensed User
Sorry, I can't figure it out with the documentation that is available...

To record I use:

B4X:
    Private AT As AudioTrack
    Private AR As AudioRecord
    Private Buffers() As Byte
    Private timer1 As Timer
    Private recordingStart As Long
    Private RP As RuntimePermissions
  
    Dim BufferSize As Int
    Dim SampleRate As Int
    Dim ChannelConfig As Int
    Dim AudioFormat As Int
    Dim AudioSource As Int
    Dim NoChnls,BitsPerSample,DataSize As Int

    AudioSource=AR.A_Src_Mic
    SampleRate=44100
    ChannelConfig=AR.Ch_Conf_Mono
    NoChnls=1
    AudioFormat=AR.Af_PCM_16
    BitsPerSample=16
  
    BufferSize=AR.GetMinBufferSize(SampleRate,ChannelConfig,AudioFormat)
  
    RP.CheckAndRequest(RP.PERMISSION_RECORD_AUDIO)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = True Then
        Activity.LoadLayout("1")
        If FirstTime Then

            AR.Initialize(AudioSource,SampleRate,ChannelConfig,AudioFormat,BufferSize)
            AT.Initialize(AT.STREAM_MUSIC, SampleRate, AT.CH_CONF_MONO, AT.AF_PCM_16, BufferSize, AT.MODE_STREAM)
          
            timer1.Initialize("timer1", 1000)
        End If
    End If

start recording:

Buffers.clear
AR.StartRecording

then stop when button is pressed:

AR.Stop

then how do I get the recorded data from AudioRecord into AudioTrack to playback ?

Or do I need to use this syntax to record with AudioRecord:

Buffers = AR.ReadBytes(0, BufferSize) ?

but still, how do I get the buffer from AudioRecord into AudioTrack ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
In AudioStream, you would just play the Buffer. Buffer contains your recording.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I don’t think that method will do what you are trying to accomplish. Depending on frequency, mono/stereo, the AudioRecord buffer may capture only milliseconds of recording before it returns the full buffer to you. If someone wants to rewind 2 seconds, than the AudioRecord buffer would not have that info. You will have to keep the buffers you record in memory or in a file. When someone hits rewind, you’ll have to determine for how long they are rewinding and then calculate how many bytes of recording that is. You then use that count to position yourself in your stored recording buffer to start the playback.
 
Upvote 0

Olivier Zeegers

Active Member
Licensed User
I don’t think that method will do what you are trying to accomplish. Depending on frequency, mono/stereo, the AudioRecord buffer may capture only milliseconds of recording before it returns the full buffer to you. If someone wants to rewind 2 seconds, than the AudioRecord buffer would not have that info. You will have to keep the buffers you record in memory or in a file. When someone hits rewind, you’ll have to determine for how long they are rewinding and then calculate how many bytes of recording that is. You then use that count to position yourself in your stored recording buffer to start the playback.

Thank you, do you know an example project ?
 
Upvote 0

Olivier Zeegers

Active Member
Licensed User
It's a long time since I looked at this.

In the Recording sub, the data is being written to a randomaccess file (outfile). If you want to keep it in memory, you can use the ByteArrayBuffer library.
https://www.b4x.com/android/forum/threads/bytearraybuffer.34306/

It will then be immediately available so you can play it with audiotrack.

Will it be fast enough when writing to a file and reading it instead of keeping the recorded audio in memory ?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I've not tried it, but it wouldn't take long to change between the two.
 
Upvote 0

Olivier Zeegers

Active Member
Licensed User
thank you so much for your time and help !

again a newbie question:

suppose I have this WAV file
how do I get AudioTrack to load this file and play it ?
With WriteByte ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0

Olivier Zeegers

Active Member
Licensed User
What does audiotrack.startrecording ? Where does it store the recorded data ?

When I use audiotrack.ReadByte I can store this in a buffer, should I call audiotrack.startrecording before ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0
Top