Android Tutorial Walkie Talkie - Audio streaming over Wifi or Bluetooth

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
This example implements a simple "walkie talkie".


(src: wikipedia)



Once the two devices are connected, either over Bluetooth or over the local network, you can press on the activity and talk. The audio captured from the microphone will be sent to the other device and played. Note that this is a half duplex solution, which means that audio will not be received while you send audio. This is to avoid positive feedback (which will also occur if the devices are close to each other).

Most of the code handles the connection. Streaming the audio is done with AudioStreamer object which was introduced in Audio library v1.5.

Note that if you are only interested in audio recording then you should follow the two examples in the above link.

The "interesting" code that is responsible for capturing the audio and sending it is quite simple:
B4X:
Sub AudioStream_RecordBuffer (Data() As Byte)
   If sendingAudio Then
      astream.Write(Data)
   End If
End Sub
Then in the other side:
B4X:
Sub astream_NewData (Buffer() As Byte)
   If sendingAudio = False Then
      'play the received audio data
      audioStream.Write(Buffer)
   End If
End Sub
 

Attachments

Mahares

Well Known Member
Licensed User
Superb ingenuity Erel!
I added this miniscule sub to the main module to speed up the IP address input of the other device:
B4X:
Sub edtIP_FocusChanged (HasFocus As Boolean)  '6/30/13
   If HasFocus Then edtIP.Text="192.168.0."  'pre-fill IP address
   edtIP.SelectionStart=edtIP.Text.Length  'place cursor at the end of text
End Sub
 

Philip Prins

Active Member
Licensed User
Bluetooth

Hello Erel,

Can i use this with my problem to send audio to a bluetooth audio module / headset from the internal mic of the smartphone?

Regards,
Philip
 

Philip Prins

Active Member
Licensed User
Hello Erel,

I want to send the audio to a bluetooth headset instead of another phone like the java example,how can i do this?

Regards,
Philip
 

Philip Prins

Active Member
Licensed User
For all interested without prefix mode you can also send and receive audio to a PC removing prefix mode with TCPIP or by using UDP send packet and receive packet.
Off course make sure that you use the same audio settings on both sides regarding samplerate bits per second etc.

When you use UDP set the receive buffer size to the right buffer for the codec ,example 320 for PCM 8000 .

Great addition Erel....
 

mvpmedia

Member
Licensed User
Is it possible to send the stream through internet? For instance can I have one device connected to wifi at home and another through 3G/4G network or another wifi? How would I go about adapting this from wifi only?
 

Ian Garton

Member
Licensed User
This is a very nice simple example for Android <--> Android voice.
I'm trying to implement a PC <--> Android version using the same Android application as Erel posted in the first post.

Using the NAudio library on the PC seems to be the simplest way to do this, let me know if you think otherwise.
For starters I'm just trying to get PC --> Android direction audio working, but am having the android application crash out after a second with an Out Of Memory exception every time the PC application starts streaming bytes to it, within about a second.

B4X:
java.lang.OutOfMemoryError
    at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.run(AsyncStreams.java:172)
    at java.lang.Thread.run(Thread.java:856)
Below is my PC side VB.net code which is performing the socket connection and audio streaming.

B4X:
Public Class Form1

    Dim WithEvents AudioIn As New NAudio.Wave.WaveIn()
    Dim SocketOut As New Net.Sockets.TcpClient
    Dim NetworkStreamOut As Net.Sockets.NetworkStream

    Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click

        AudioIn.DeviceNumber = 0   ' PC Microphone
        AudioIn.WaveFormat = New NAudio.Wave.WaveFormat(22050, 16, 1)   ' Sample Rate, Bits per Sample, Channels

        SocketOut.Connect("192.168.0.14", 21341)    ' Android Device IP
        Do While Not SocketOut.Connected
            Application.DoEvents()
        Loop

        AudioIn.StartRecording()
        NetworkStreamOut = SocketOut.GetStream

    End Sub


    Private Sub AudioIn_DataAvailable(sender As Object, e As NAudio.Wave.WaveInEventArgs) Handles AudioIn.DataAvailable

        If e.Buffer.Length > 0 Then
            NetworkStreamOut.Write(e.Buffer, 0, e.Buffer.Length)
            NetworkStreamOut.Flush()
        End If

    End Sub

End Class
Any thoughts or ideas most welcome!
 

realblue

Member
Licensed User
Hi Erel I get the following error as soon as the application starts.

B4X:
--------- beginning of /dev/log/system
java.net.SocketException: Connection timed out
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Installing file.
PackageAdded: package:b4a.example.walkietalkie
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (connector) Create **
connector_service_create (B4A line: 36)
audioStream.Initialize("AudioStream", 22050, True, 16, audioStream.VOLUME_MUSIC)
java.lang.NegativeArraySizeException
    at anywheresoftware.b4a.audio.AudioStreamer.Initialize(AudioStreamer.java:69)
    at b4a.example.walkietalkie.connector._service_create(connector.java:521)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.walkietalkie.connector.onCreate(connector.java:42)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1949)
    at android.app.ActivityThread.access$2500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:989)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3689)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Unable to create service b4a.example.walkietalkie.connector: java.lang.RuntimeException: java.lang.NegativeArraySizeException
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1959)
    at android.app.ActivityThread.access$2500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:989)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3689)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.NegativeArraySizeException
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:195)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.walkietalkie.connector.onCreate(connector.java:42)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1949)
    ... 10 more
Caused by: java.lang.NegativeArraySizeException
    at anywheresoftware.b4a.audio.AudioStreamer.Initialize(AudioStreamer.java:69)
    at b4a.example.walkietalkie.connector._service_create(connector.java:521)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    ... 13 more
The libraries are used :

Audio 1.50
Core 2.71
Dialogs 2.80
IME 1.05
Network 1.24
Phone 2.10
RandomAccesFile 1.32
Reflection 2.40
Serial 1.23

And the device is GT-I9003 running Android version 2.3.6

Edit : If I use sample rate 44100 instead of 22050 the error goes away
 
Last edited:

realblue

Member
Licensed User
For all interested without prefix mode you can also send and receive audio to a PC removing prefix mode with TCPIP or by using UDP send packet and receive packet.
Off course make sure that you use the same audio settings on both sides regarding samplerate bits per second etc.

When you use UDP set the receive buffer size to the right buffer for the codec ,example 320 for PCM 8000 .

Great addition Erel....
Hi Philip,

I am trying to send audio and video from android device to PC. What I need is to send video one way (Android to PC) but send and receive audio both ways. I am able to send audio byte array to the PC but I cannot play it. You mentioned "without prefix mode" which I didn't quite understand. Would you be more specific or better show me a code sample?
 

Philip Prins

Active Member
Licensed User
Hi Philip,

I am trying to send audio and video from android device to PC. What I need is to send video one way (Android to PC) but send and receive audio both ways. I am able to send audio byte array to the PC but I cannot play it. You mentioned "without prefix mode" which I didn't quite understand. Would you be more specific or better show me a code sample?
Hi Philip,

I am trying to send audio and video from android device to PC. What I need is to send video one way (Android to PC) but send and receive audio both ways. I am able to send audio byte array to the PC but I cannot play it. You mentioned "without prefix mode" which I didn't quite understand. Would you be more specific or better show me a code sample?
I can send you the code but it is to big to upload, send me your email adress
 

Philip Prins

Active Member
Licensed User
Hello All

Audio streaming works fine both ways on phone but on a tablet i can only receive audio,if i Log the packet length and monitor with wire shark i see data being received on the PC .But i have no audio....
When i compare the stream data from the phone it is a steady data stream but from the tablet there are empty packets in between.I use UDP send packet.
 
Last edited:

realblue

Member
Licensed User
Hello All

Audio streaming works fine both ways on phone but on a tablet i can only receive audio,if i Log the packet length and monitor with wire shark i see data being received on the PC .But i have no audio....
When i compare the stream data from the phone it is a steady data stream but from the tablet there are empty packets in between.I use UDP send packet.
Hi Philip,

In my project sound and video is OK from Android to PC, but the sound from PC to Android is very poor. I am using http://naudio.codeplex.com/ components to play sound on the PC.
 
Status
Not open for further replies.
Top