B4J Question Byte To Audio File

mohammad be

Member
Hello
I have a voice call app
And now I can establish voice communication between Android devices through a server
I want to save the input information from each device to an audio file.
I used the following code, the file is created, but unfortunately the files are not saved in audio format
Please help
Server B4j:
Sub astream_NewData (Buffer() As Byte)
    Dim Rec_data1 As MyMessage
    Rec_data1.Initialize
    Rec_data1 = ser.ConvertBytesToObject(Buffer)
    Dim bb() As Byte
    bb=Rec_data1.Voice
    Dim Sen_data1 As MyMessage
    Sen_data1.Initialize
    Sen_data1.Code=Rec_data1.Code
    Sen_data1.Voice=bb
    Dim bb11() As Byte
    bb11=ser.ConvertObjectToBytes(Sen_data1)
    If Rec_data1.Code=2 Then
        For i=UsersCall2.Size-1 To 0 Step -1
            Dim t As SOK=UsersCall2.Get(i)
            If t.so.RemoteAddress.Trim=Rec_data1.Rec.Trim Then
                Sock2=t.so
                astream2.Write(bb11)
                BytesToFile(File.DirApp,Rec_data1.Code&".wav",bb11)
                Exit
            End If
        Next
    End If
End Sub

public Sub BytesToFile (Dir As String, FileName As String, Data() As Byte)
    Dim out As OutputStream = File.OpenOutput(Dir, FileName, True)
    out.WriteBytes(Data, 0, Data.Length)
    out.Close
End Sub
 

mohammad be

Member
Hello
thank you
What I want to do
The audio input is entered in bytes and I want to save it on a sound file and this continues and is added to the file each time
I did this, but my file format is not audio, it is of the byte type. In line 19, the code I sent is clear. No sound is a normal file. Now I have to convert the bytes to audio data before saving the bytes in the file and then add them to the file on line 28.
I need a code or function or library to do this conversion
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
As I said, you need to write a correctly formatted header to the file, you can find the required code in the examples I have given.

The B4a project is doing something very similar and may be easier to adapt.
 
Upvote 0

Midimaster

Active Member
Licensed User
You need to add additional 44Bytes at the beginning of your file. This is called a "header". After this 44 Bytes join the samples as they arrived you from the recording.

Steve points you to a zip file (from Erel) where you can find this Sub:
B4X:
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

This SUB writes the first 44 bytes. Then follows your recording:
B4X:
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

At the end you have to correct two values in the header. They descripe the length of the file and can only be set at the end of the recording.
B4X:
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

Study the complete code here: https://www.b4x.com/android/forum/attachments/recordtowavefile-zip.18108/
 
Upvote 0

mohammad be

Member
You need to add additional 44Bytes at the beginning of your file. This is called a "header". After this 44 Bytes join the samples as they arrived you from the recording.

Steve points you to a zip file (from Erel) where you can find this Sub:
B4X:
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

This SUB writes the first 44 bytes. Then follows your recording:
B4X:
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

At the end you have to correct two values in the header. They descripe the length of the file and can only be set at the end of the recording.
B4X:
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

Study the complete code here: https://www.b4x.com/android/forum/attachments/recordtowavefile-zip.18108/
Thank you
 
Upvote 0

mohammad be

Member
As I said, you need to write a correctly formatted header to the file, you can find the required code in the examples I have given.

The B4a project is doing something very similar and may be easier to adapt.
Hello
Thankful
Yes you are right
But I have to do this on the server
thanks again
 
Upvote 0
Top