Android Question Record a wav file in B4i and play in B4A

yaqoob

Active Member
Licensed User
Longtime User
Hello,

I am using this example to send a wave file through MQTT between two applications, one written in B4i and the other in B4A. The B4i can play a B4A wave file recorded in B4A, but B4A cannot play a wave file recorded by B4i.

B4i code
Code:
sub btnStartRecording_Click
    streamer.Initialize(File.DirDocuments, mFileName, 44100, True, 16, False)

        streamer.Record
        timer1.Enabled = True
        Timer1_Tick
Catch
Log("btnRecord_Click " &  LastException.description)
End Try
End Sub


Sub btnsumbitSound_Click
   
    Starter.SendAudio(File.ReadBytes(File.DirDocuments, mFileName))

End Sub


Public Sub SendAudio(SoundData() As Byte)
    If connected Then
        SBS.Initialize
        SBS.Append("Recored").Append("/Audiosend")
        Dim sendAudioStr As String=SBS.ToString
        client.Publish2(sendAudioStr, serializator.ConvertObjectToBytes(SoundData),1,False)
    Else
        hd.ToastMessageShow("It is not connected",False)
       
    End If

End Sub

B4a Code

B4A code:
Private Sub client_MessageArrived (Topic As String, Payload() As Byte)
Dim receivedObject As Object = serializator.ConvertBytesToObject(Payload)
        Dim WaveSound() As Byte = receivedObject
        Dim SendFileName As String
        Dim SBS As StringBuilder
        SBS.Initialize
        SBS.Append("filename").Append(".wav")
        SendFileName=SBS.ToString  
    BytesToFile (File.DirInternal,SendFileName, WaveSound)
           
End Sub

Sub play_click

If filename.EndsWith(".wav") Then
   
           
            mp.Load(File.DirInternal,filename)
           
                    mp.Play
        End If
End Sub
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Private Sub client_MessageArrived (Topic As String, Payload() As Byte) Dim WaveSound() As Byte = receivedObject
should´nt be WaveSound() filled with payload? Where comes WaveSound() comes from? and what is receivedObject?
 
Upvote 0

yaqoob

Active Member
Licensed User
Longtime User
The original application has many lines. This is a portion of the application. I have added the following line to make it more clear.

Dim receivedObject As Object = serializator.ConvertBytesToObject(Payload)

The WaveSound() gets data from recievedObject and receiveObject gets it from payload.
 
Upvote 0

yaqoob

Active Member
Licensed User
Longtime User
Please can you explain more about waveheader? B4i can play B4A wave files without any header
 
Upvote 0

emexes

Expert
Licensed User
Hello,

I am using this example to send a wave file through MQTT between two applications, one written in B4i and the other in B4A. The B4i can play a B4A wave file recorded in B4A, but B4A cannot play a wave file recorded by B4i.

Can B4I play a "wave" file recorded by B4I?

Also, how does the "wave" file receiver know whereabouts is the end of the string at the start of the file? Are client.Publish2() and BytesToFile adding separators eg CRLF after each string field?
 
Upvote 0

yaqoob

Active Member
Licensed User
Longtime User
Yes, B4i can play a wave file recorded by B4i
B4A can play a wave file recorded by B4A
B4i can play a wave file recorded by B4A
B4A can not play a file recorded by B4I this is the issue
 
Upvote 0

emexes

Expert
Licensed User
Yes, B4i can play a wave file recorded by B4i
B4A can play a wave file recorded by B4A
B4i can play a wave file recorded by B4A
B4A can not play a file recorded by B4I this is the issue

Ok, step one would be to log the first few bytes of the sent and received audio data.

In particular, if they are 16-bit values and are misaligned one byte, then it will just play as noise.
 
Upvote 0

emexes

Expert
Licensed User
I'm uncertain about this too:

B4X:
Private Sub client_MessageArrived (Topic As String, Payload() As Byte)
Dim receivedObject As Object = serializator.ConvertBytesToObject(Payload)
        Dim WaveSound() As Byte = receivedObject

It takes the incoming Array of Bytes, converts it to an Object, and then back to an(other) Array of Bytes.

Payload() As Byte ➟ receivedObject As Object ➟ WaveSound() As Byte

That seems somewhat redundant. At best it'll end up where it started; more likely, it's going to add object-wrapper bytes that move us even further away from a standard audio file format.
 
Last edited:
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Please can you explain more about waveheader? B4i can play B4A wave files without any header
Hi, check #10 post of your referenced example, there are codes of how to write waveheader and number of samples to the *.wav file.

Without waveheader, mediaplayer can't know what sampling rate and how many bits for one sample it should use to play the PCM data. I don't know whether there is a default parameter set for mediaplayer to try to play raw PCM data without waveheader but that's not a good practice.
 
Upvote 0
Top