Android Question AudioStreamer and buffer size

PassionDEV

Well-Known Member
Licensed User
i am using audio streamer to record and audio from microphone

thats how i initialize the audio streamer

B4X:
audioStream.Initialize2(1, "AudioStream", 8000, True, 16, audioStream.VOLUME_MUSIC)

B4X:
Sub AudioStream_RecordBuffer (Data() As Byte)

Dim Packet As UDPPacket

ToastMessageShow(Data.Length, False)
End Sub

on some phones the data.length is too big gives 2048 and some phones its 640

i wanted to low that big length 2048

like dividing the big number by 4

i have been doing this in other ide like following

B4X:
BUFFSIZE := TJAudioRecord.JavaClass.getMinBufferSize(8000,
TJAudioFormat.JavaClass.CHANNEL_IN_MONO,
TJAudioFormat.JavaClass.ENCODING_PCM_16BIT);
stream := TJavaArray<byte>.Create(BUFFSIZE div 4);

AudioRecorder := TJAudioRecord.JavaClass.init
(TJMediaRecorder_AudioSource.JavaClass.MIC, 8000,
TJAudioFormat.JavaClass.CHANNEL_IN_MONO,
TJAudioFormat.JavaClass.ENCODING_PCM_16BIT, BUFFSIZE);

(AudioRecorder as JAudioRecord).startRecording;

so stream 2048 is divided by 4 should give 512 i couldn't figure how to do the same in b4a
 

PassionDEV

Well-Known Member
Licensed User
here is the full code of sending in b4a

B4X:
Sub AudioStream_RecordBuffer(Data() As Byte)

Dim Packet As UDPPacket
Dim datasent As Int
Dim in As InputStream
Dim out As OutputStream
Dim sentdata() As Byte


If Data.Length >= 1000 Then
datasent = Data.Length/4
Else
datasent = Data.Length
End If

in.InitializeFromBytesArray(Data, 0, datasent)
out.InitializeToBytesArray(0)
File.Copy2(in, out)
    
sentdata = out.ToBytesArray


Log(sentdata.Length)

If sendingAudio Then
Packet.Initialize(sentdata, genaudioip, genaudioport)
UDPSck.Send(Packet)

End If

in.Close
out.Close

End Sub
 
Upvote 0

OliverA

Expert
Licensed User
Notes:
1) Untested code
2) If Record_Buffer event is called before all packets are sent, you will have issues. If this is a problem, then you need to implement a queue type system for the incoming Data().
B4X:
Sub AudioStream_RecordBuffer(Data() As Byte)
   If sendingAudio And Data.Length > 0 Then
       Dim dataLength As Int = Data.Length
       'Adjust as to the maximum amount of data to sent via UDP. Please note
       ' that the actuall UDP packet will be larger (data, plus UDP header, plus any
       ' encapsulations)
       Dim maxSizeToSent As Int = 1000
       Dim packetsToSent As Int = (dataLength/maxSizeToSent)+1
       Dim packetSize As Int
       If dataLength > maxSizeToSent Then
           packetSize = maxSizeToSent
       Else
           packetSize = dataLength
       End If
       Dim x As Int
       For x = 1 To packetsToSent
           Dim packet As UDPPacket
           Log(packetSize)
           packet.Initialize2(Data, (x-1) * maxSizeToSent, packetSize, genaudioip, genaudioport)
           UDPSck.Send(packet)
           dataLength = dataLength - maxSizeToSent
           If dataLength > maxSizeToSent Then
               packetSize = maxSizeToSent
           Else
               packetSize = dataLength
           End If
       Next
   End If
End Sub
 
Upvote 0

PassionDEV

Well-Known Member
Licensed User
wow what are you a pure genius that work like a charm i will look for adjust it to a queue thank you very much
 
Upvote 0

OliverA

Expert
Licensed User
This version includes buffering of the incoming Data(). I also modified the original processing of the Data() by not tracking packet size (no need to), removing the if/then statements and multiplications. Finally, I unrolled the last loop in the for/next loop.

This version needs 3 extra global variables:
B4X:
Private audioList As List
Private audioListPtr As Int
Private audioListProcessing As Boolean
and you need to initialize/set their values the following before starting a new recording
B4X:
audioList.Initialize
audioListPtr = 0
audioListProcessing = False
B4X:
Sub AudioStream_RecordBuffer(Data() As Byte)
   If sendingAudio = False Then Return           'Why bother if were not going to send the audio
   If Data.Length < 1 Then Return               'Sanity check
   audioList.Add(Data)                           'Buffer the incoming data
   If audioListProcessing = True Then Return   'Quit if we are currently processing the audio list
   
   audioListProcessing = True                   'Flag audio processing and
   'Adjust to the maximum amount of data To sent via UDP. Please note
   ' that the actuall UDP packet will be larger (data, plus UDP header, plus any
   ' encapsulations)
   Dim maxSizeToSent As Int = 1000
   Dim dataLength As Int
   Dim packetsToSent As Int
   Dim offset As Int
   Dim x As Int
   Do While audioListProcessing               ' let us process some audio
       Dim audioData() As Byte = audioList.Get(audioListPtr)
       dataLength = audioData.Length
       packetsToSent = (dataLength/maxSizeToSent)+1
       offset = 0
       'Sent all but the last packet with the For Loop. Loop Is skipped If only one packet
       ' needs To be sent.
       For x = 1 To packetsToSent - 1
           Dim packet As UDPPacket
           packet.Initialize2(audioData, offset, maxSizeToSent, genaudioip, genaudioport)
           UDPSck.Send(packet)
           offset = offset + maxSizeToSent
       Next
       'Sent the last Or only packet
       Dim packet As UDPPacket
       packet.Initialize2(audioData, offset, dataLength - offset, genaudioip, genaudioport)
       UDPSck.Send(packet)
       audioList.Set(audioListPtr, Null)       'Done with the data
       audioListPtr = audioListPtr + 1           'Increment the list pointer
       If audioListPtr = audioList.Size Then   'If we reached the end of the audio list
           audioListProcessing = False           ' then we are done processing the audio list
       End If
   Loop
End Sub
 
Upvote 0
Top