From Java side: generated a short array spanning from -32768 to 32767, and converted it in the form of two bytes. The byte buffer (131072 bytes) is then saved in a local directory.
final byte[] DeleteBuffer = new byte[131072];
byte byte1, byte2;
for (int i=0;i<65536;i++) {
short tmp = (short) (i-32768);
byte1 = (byte) (tmp&0xFF); // the low byte
byte2 = (byte) ((tmp>>8)&0xFF); // the high byte
DeleteBuffer[i*2] = byte1;
DeleteBuffer[i*2+1] = byte2;
if (i%1000==0){
Log.w("Test",Short.toString(tmp));
}
}
FileOutputStream os = null;
try {
os = new FileOutputStream(new File(mFileNamedelete));
os.write(DeleteBuffer);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
From Matlab side: read in the byte array and process as follows to recover the original data.
fi = fopen('QL_Record2','r');
ByteData = fread(fi); % double format
fclose(fi)
B1 = ByteData(1:2:end); % the low byte
B2 = ByteData(2:2:end); % the high byte
Index = B2>=128; % negative values
B2(Index) = B2(Index)-256;
T = B2*256+B1; % the recovered array
However, if we transfer the data via UDP server directly to matlab, it is a little bit different. The main reason behind is the saving format is unssigned int8 or signed int8.
From Java side: a thread that contains a UDP socket is defined.
public void testStreaming()
{
final Handler handler = new Handler();
Thread testudpSendThread = new Thread(new Runnable() {
@Override
public void run() {
//while(true){
// pause the programme for 1ooo milliseconds
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final byte[] DeleteBuffer = new byte[131072];
byte byte1, byte2;
for (int i=0;i<65536;i++) {
short tmp = (short) (i-32768);
byte1 = (byte) (tmp&0xFF); // the low byte
byte2 = (byte) ((tmp>>8)&0xFF); // the high byte
DeleteBuffer[i*2] = byte1;
DeleteBuffer[i*2+1] = byte2;
// if (i%1000==0){
// Log.w("Test",Short.toString(tmp));
// }
}
try {
DatagramSocket socket = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName(IP_ADDRESS);
byte[] tmpp = new byte[2048];
for(int i=0;i<64;i++) {
//DatagramPacket packet = new DatagramPacket(DeleteBuffer, 131072, serverAddr, 50007);
//new Random().nextBytes(tmpp);
tmpp = Arrays.copyOfRange(DeleteBuffer,i*2048,(i+1)*2048);
DatagramPacket packet = new DatagramPacket(tmpp, 2048, serverAddr, 50007);
Log.w("Test","Packet generated");
try {
// send the UDP packet
socket.send(packet);
Log.w("UDP", "C: Packet sent!");
} catch (Exception e) {
e.printStackTrace();
Log.w("UDP", "C: Sending just failed");
}
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
socket.close();
}catch (Exception e) {
e.printStackTrace();
}
FileOutputStream os = null;
try {
os = new FileOutputStream(new File(mFileNamedelete));
os.write(DeleteBuffer);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
//start the streaming thread
testudpSendThread.start();
}
If we want to covert back the two bytes to a short variable directly, the following process can be applied in the java side directly. For instance, the UDP receiver grabs the data package in the form of byte array, and we want to get the original short array. shortBuffer equals shortBuffer2, and of course, using the shift operator is a better choice.
// byte to short
byte[] buffer = dp.getData();
int Sample = buffer.length/2;
short LSB, MSB;
short shortrecover;
if (Sample>1){
short[] shortBuffer = new short[Sample];
short[] shortBuffer2 = new short[Sample];
for (int i=0;i<Sample;i++){
LSB = (short) buffer[i*2];
MSB = (short) buffer[i*2+1];
if (LSB<0){
shortrecover = (short) (MSB*256 + LSB + 256);
} else {
shortrecover = (short) (MSB*256 + LSB);
}
shortBuffer[i] = shortrecover;
shortrecover = (short) ( (MSB<<8) | LSB&0xFF );
shortBuffer2[i] = shortrecover;
}
Log.w("UDP", "C: short1: " + Arrays.toString(Arrays.copyOfRange(shortBuffer, 0, 50)));
Log.w("UDP", "C: short2: " + Arrays.toString(Arrays.copyOfRange(shortBuffer2, 0, 50)));
From Matlab side: we accept the data and recover them. Note this time we correct the lower byte instead of the higher byte. The judp function is avaialble here.
For instance, if we want to send away a frame of audio data ranging from [-1,1) presented in 16bits
clear all; close all; clc
blockData = linspace(-1,1,10001);blockData = blockData(1:end-1);
blockData = round(blockData*32768);
% convert the 16bit to 2 8bit data
highData = floor(blockData/256);
lowData = blockData-highData*256;
lowData(lowData>127) = lowData(lowData>127)-256;
highData8bit = int8(highData);
lowData8bit = int8(lowData);
UDPData = reshape([lowData8bit;highData8bit],1,[]);
judp('send',50007,'0.0.0.0',UDPData);
clear all; close all; clc
Data = [];
frameN = 0;
status = 1;
while(status)
try
mssg = judp('receive',50007,2048);
length(mssg)
Data = [Data;mssg];
frameN = frameN+1
if frameN>=64,
pause(1)
status=0;
end
catch
end
end
ByteData = Data; % Instead of the double format as earlier from a file, here we get int8 format
B1 = double(ByteData(1:2:end));
B2 = double(ByteData(2:2:end));
figure;
yyaxis left
plot(B1)
yyaxis right
plot(B2);
Index = B1<0;
B1(Index) = B1(Index)+256;
T = zeros(size(B1));
T(:) = B2*256+B1;
figure;plot(T);