I have an android activity that connects to a java class and sends it data packets in the form of sockets. The class receives sound packets and throws them onto the PC speakers. The code works fine, but there is constant jitter / interrupt when sound is played in PC speakers.
Android Activity:
public class SendActivity extends Activity { private Button startButton, stopButton; public byte[] buffer; public static DatagramSocket socket; private int port = 50005; AudioRecord recorder; private int sampleRate = 8000; @SuppressWarnings("deprecation") private int channelConfig = AudioFormat.CHANNEL_IN_MONO; private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); private boolean status = true; int bufferSizeInBytes; int bufferSizeInShorts; int shortsRead; short audioBuffer[]; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send); startButton = (Button) findViewById(R.id.start_button); stopButton = (Button) findViewById(R.id.stop_button); startButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { status = true; startStreaming(); } }); stopButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { status = false; recorder.release(); Log.d("VS", "Recorder released"); } }); minBufSize += 5120; System.out.println("minBufSize: " + minBufSize); } public void startStreaming() { Thread streamThread = new Thread(new Runnable() { @Override public void run() { try { DatagramSocket socket = new DatagramSocket(); Log.d("VS", "Socket Created"); byte[] buffer = new byte[minBufSize]; Log.d("VS", "Buffer created of size " + minBufSize); DatagramPacket packet;
Android layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".SendActivity" > <Button android:id="@+id/stop_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/start_button" android:layout_alignBottom="@+id/start_button" android:layout_toRightOf="@+id/start_button" android:text="Stop" /> <Button android:id="@+id/start_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="79dp" android:layout_marginTop="163dp" android:text="Start" /> </RelativeLayout>
Android Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.audiostreamsample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission> <uses-permission android:name="android.permission.INTERNET" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.audiostreamsample.SendActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Class for receiving data packets and outputting them to PC speakers:
class Server { AudioInputStream audioInputStream; static AudioInputStream ais; static AudioFormat format; static boolean status = true; static int port = 50005; static int sampleRate = 8000; public static void main(String args[]) throws Exception { DatagramSocket serverSocket = new DatagramSocket(50005); byte[] receiveData = new byte[5000]; format = new AudioFormat(sampleRate, 16, 1, true, false); while (status == true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); ByteArrayInputStream baiss = new ByteArrayInputStream( receivePacket.getData()); ais = new AudioInputStream(baiss, format, receivePacket.getLength()); toSpeaker(receivePacket.getData()); } } public static void toSpeaker(byte soundbytes[]) { try { DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format); SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); sourceDataLine.open(format); FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN); volumeControl.setValue(6.0206f); sourceDataLine.start(); sourceDataLine.open(format); sourceDataLine.start(); System.out.println("format? :" + sourceDataLine.getFormat()); sourceDataLine.write(soundbytes, 0, soundbytes.length); System.out.println(soundbytes.toString()); sourceDataLine.drain(); sourceDataLine.close(); } catch (Exception e) { System.out.println("Not working in speakers..."); e.printStackTrace(); } } }
If you want to test the application in your IDE, just create two different projects: one for the Android application and one for the server class.
In the Android application, just add the IP address of your device and run the application on the device, the mobile and the computer must belong to the same network. Please execute the server class as a Java application.
Jitter will be noticeable and annoying, but voices will be more or less clear. Please suggest me what to do to get a clearer result.