Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am developing android musical piano application. in which i am using soundpool to play audios but how can i record sound so that user can sing and record his own voice along with recording music beats
Here are wo functions one for recording and other for playing
private void startRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try {
file.createNewFile();
recording=true;
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(SmpleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
SmpleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
AudioManager audio=(AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
audio.setMicrophoneMute(true);
//int sessionId=audioRecord.getAudioSessionId();
// NoiseSuppressor.create(sessionId);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
void playRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int shortSizeInBytes = Short.SIZE/Byte.SIZE;
int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while(dataInputStream.available() > 0){
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
SmpleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Related
i am trying to transfer large file over java socket transfer happen sucessfully but the file recieved miss some data or some bytes in my opinion. (completely new to the sockets)
Server Side Code
try {
File img = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/abc.mkv");
byte[] mybytearr = new byte[8192];
FileInputStream fis = new FileInputStream(img);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
long len = fis.read();
DataOutputStream dos = new DataOutputStream(outputStream);
int read;
while ((read = dis.read(mybytearr)) != -1) {
dos.write(mybytearr, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
Client Side Code
try {
if (inputStream.available() != 0) {
int bytesRead;
int bufferSize = 0;
bufferSize = socket.getReceiveBufferSize();
DataInputStream dis = new DataInputStream(inputStream);
String name = dis.readUTF();
File db = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "abc.mkv");
FileOutputStream output = new FileOutputStream(db);
byte[] buffer = new byte[bufferSize];
int read;
while((read = dis.read(buffer)) !=-1) {
output.write(buffer,0,read);
}
}
} catch (IOException e) {
e.printStackTrace();
}
This question already has answers here:
Java sending and receiving file (byte[]) over sockets
(6 answers)
Closed 7 years ago.
I was experimenting with JAVA and found this question online.
Java sending and receiving file (byte[]) over sockets.
Just for curiosity i played with the code in the accepted answer, and with other code i found similar to the question. I tried the accepted answer,yes it works and is very fast. But the problem is Archive files are getting corrupted. So here is other code i tried. The downfall of my experimental code is it consume CPU cycles and takes more time than accepted answer (And i have no idea why it is happening so). So here is my code. Can somebody help me to optimize and improve this code more.
Time Taken by accepted Answer = 11ms for 4 Mb file.
Time taken by my experiment= 4 seconds for same file.
Server.java
public class Server implements Runnable {
private ServerSocket serverSocket = null;
private Socket socket = null;
private ObjectInputStream inStream = null;
public Server() {
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(4445);
socket = serverSocket.accept();
DataInputStream dIn = new DataInputStream(socket.getInputStream());
OutputStream os = socket.getOutputStream();
DataOutputStream outToClient = new DataOutputStream(os);
System.out.println("Connected");
File myFile = new File("lib1.zip");
long flength = myFile.length();
System.out.println("File Length"+flength);
outToClient.writeLong(flength);
FileInputStream fis;
BufferedInputStream bis;
byte[] mybytearray = new byte[8192];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
int theByte = 0;
System.out.println("Sending " + myFile.getAbsolutePath() + "(" + myFile.length() + " bytes)");
while ((theByte = bis.read()) != -1) {
outToClient.write(theByte);
// bos.flush();
}
/*int count;
BufferedOutputStream bos= new BufferedOutputStream(os);
while ((count = bis.read(mybytearray))>0) {
bos.write(mybytearray, 0, count);
}*/
bis.close();
socket.close();
} catch (SocketException se) {
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread t = new Thread(new Server());
t.start();
}
}
ReceiveFile.java
public class RecieveFile {
public final static int SOCKET_PORT = 4445; // you may change this
String SERVER = "127.0.0.1"; // localhost
ArrayList<String> logmsg = new ArrayList<>();
public static void main(String[] args) {
new RecieveFile();
}
public RecieveFile() {
try (Socket sock = new Socket(SERVER, SOCKET_PORT)) {
System.out.println("Connecting...");
try (OutputStream os = sock.getOutputStream(); DataOutputStream outToServer = new DataOutputStream(os)) {
try (DataInputStream dIn = new DataInputStream(sock.getInputStream())) {
long fileLen, downData;
int bufferSize = sock.getReceiveBufferSize();
long starttime = System.currentTimeMillis();
File myFIle = new File("lib1.zip");
try (FileOutputStream fos = new FileOutputStream(myFIle); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
fileLen = dIn.readLong();
/*for (long j = 0; j <= fileLen; j++) {
int tempint = is.read();
bos.write(tempint);
}*/
downData = fileLen;
int n = 0;
byte[] buf = new byte[8192];
while (fileLen > 0 && ((n = dIn.read(buf, 0, buf.length)) != -1)) {
bos.write(buf, 0, n);
fileLen -= n;
// System.out.println("Remaining "+fileLen);
}
/*while ((n = dIn.read(buf)) > 0) {
bos.write(buf, 0, n);
}*/
bos.flush();
long endtime = System.currentTimeMillis();
System.out.println("File " + myFIle.getAbsolutePath()
+ " downloaded (" + downData + " bytes read) in " + (endtime - starttime) + " ms");
}
}
}
} catch (IOException ex) {
Logger.getLogger(RecieveFile.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You're copying a byte at a time. This is slow. You're also declaring a byte array but not using it. Try this:
int count;
byte[] buffer = new byte[8192]; // or more, double or quadruple it
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Your solution takes a lot of time probably because you are reading a character at time, instead of all the buffer.
The solution is to use a construct similar to the linked question; the problem you got about corrupted file is really improbable, a malformed TCP packed that pass CRC check is really rare occurrence, and I would blame a bug instead. try to post the code you used. But you can add some hash check on the file and some part of it, if you are concerned about this
Here is a cleaned up version of your code, it should perform faster as it avoids single byte operations:
public class Server implements Runnable {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(4445);
Socket socket = serverSocket.accept();
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
File myFile = new File("lib1.zip");
long flength = myFile.length();
dos.writeLong(flength);
InputStream fis = new FileInputStream(myFile);
byte[] buf = new byte[16*1024]; // 16K
long written = 0;
while ((count = fis.read(buf))>0) {
dos.write(buf, 0, count);
written+=count;
}
if (written != flength)
System.out.println("Warning: file changed");
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
System.exit();
}
}
An possible improvement would be to use NIO with channel.sendTo() but this should already have an acceptable performance. Note you do not need to use buffered streams on reading or writing as you use a larger byte array buffer anyway.
One possible improvement would be to not use the DataOutputStream for the long but poke the 8 bytes of it into the first buffer (array) write.
BTW: writing 4MB in 11ms is 390MB/s, that would be faster than most desktop disks can read and write.
i am recording a pcm file thorugh AudioRecorder and create a file in sdcard. when recording is done i play the same file with Audiotrack but it crash. in logcat it says "Invalid audio buffer size". also my file size on sdcard is 0.0kb ,which i didn't understand why. here is the code. `
public void startRecord() {
File file = new File(Environment.getExternalStorageDirectory(),
"test.pcm");
int sampleFreq = 11025;
try {
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(
bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize);
audioRecord.startRecording();
while (recording) {
int numberOfShort = audioRecord.read(audioData, 0,
minBufferSize);
for (int i = 0; i < numberOfShort; i++) {
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void PLaying(int explosion) {
File file = new File(Environment.getExternalStorageDirectory(),
"test.pcm");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int bufferSizeInBytes = (int) (file.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(
inputStream);
DataInputStream dataInputStream = new DataInputStream(
bufferedInputStream);
int i = 0;
while (dataInputStream.available() > 0) {
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
int sampleFreq = explosion;
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleFreq, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
`
Do You have integrated the stop method? Please Show us a Little bit more code. The Problem is, if You haven´t implemented a correct stop mehtod, it will Loop forever..Have You done something like this:
yourStopButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view){
recording=false;
}
});
And then, don´t Forget to do the same in onStart and set recording to true.
This code looks dodgy
while (recording) {
int numberOfShort = audioRecord.read(audioData, 0,
minBufferSize);
for (int i = 0; i < numberOfShort; i++) {
dataOutputStream.writeShort(audioData[i]);
}
}
What is the value of recording. Where does the value change. If it does not change it will be an endless loop (unless and exception is thrown).
Divide the minimum buffer size by 2 when constructing the AudioRecord instance
First of all, if not using function decode_path , I can play .wav file with my code , and it works fine I use Jlayer and audio track to play the song.
Second, if I use function decode_path it can decode mp3 to pcm file , and pass the byte[] to function PlayAudioTrack, and let it play.
The quesion is,I don't know where my code is wrong , I use 320Kbps, 44.1Khz stereo type, Layer3 mp3, but the AudioTrack plays noise but no music~!!!!
can anyone ?
???
My code
public void PlayAudioTrack(String filePath) throws IOException{
int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
//Reading the file..
int count = 512 * 1024; // 512 kb
// byte[] byteData = null;
// byteData = new byte[(int)count];
//we can decode correct byte data here
byte[] byteData = null;
byteData = decode_path(filePath, 0, 20000);
File file = null;
file = new File(filePath);
FileInputStream in = null;
try {
in = new FileInputStream( file );
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int bytesread = 0, ret = 0;
int size = (int) file.length();
at.play();
while (bytesread < size) {
Log.e("devon","write byte array with sizes");
ret = in.read( byteData,0, count);
if (ret != -1) {
Log.e("devon","Write the byte array to the track");
at.write(byteData,0, ret);
bytesread += ret;
}else break;
}
at.stop();
at.release();
}
public static byte[] decode_path(String path, int startMs, int maxMs)
throws IOException{
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
float totalMs = 0;
boolean seeking = true;
File file = new File(path);
InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024);
try {
Bitstream bitstream = new Bitstream(inputStream);
Decoder decoder = new Decoder();
boolean done = false;
while (! done) {
Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (! seeking) {
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
if (output.getSampleFrequency() != 44100
|| output.getChannelCount() != 2) {
throw new IllegalArgumentException("mono or non-44100 MP3 not supported");
}
short[] pcm = output.getBuffer();
for (short s : pcm) {
outStream.write(s & 0xff);
outStream.write((s >> 8 ) & 0xff);
}
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
return outStream.toByteArray();
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
Log.w(TAG, "Decoder error", e);
throw new IOException("Decoder error: " + e);
}
}
public void PlayAudioTrack(String filePath) throws IOException{
int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
//Reading the file..
int count = 512 * 1024; // 512 kb
// byte[] byteData = null;
// byteData = new byte[(int)count];
//we can decode correct byte data here
byte[] byteData = null;
byteData = decode_path(filePath, 0, 20000);
int temp =0;
at.play();
while (temp<byteData.length)
{
at.write(byteData, temp, count);
temp+= count;
}
at.stop();
at.release();
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So.. i have a server socket, here:
ServerSocket server = new ServerSocket(5000);
while(true){
Socket cliente = server.accept();
Thread thread = new Thread(new Converter(cliente));
thread.start();
My app converts a Word document (.doc) to a PDF. First my server receives a .doc, makes a conversion, after a response with .pdf archive.
How do I get the client that is waiting for a response?
If I understand you correctly, you are creating one thread per each accepted socket (thus client). This Converter thread has access to client socket (every client has a different socket returned by accept()). Now the solution is quite simple:
public void run() {
cliente.getInputStream(); //read .doc first
//do the conversion to .pdf
cliente.getOutputStream(); //send .pdf back
}
get:
private void getDocArchive(){
try {
InputStream in = socket.getInputStream();
BufferedInputStream buffer = new BufferedInputStream(in, 1024);
byte[] b = new byte[1024];
int len = 0;
int bytcount = 1024;
FileOutputStream out = new FileOutputStream("docs/atual.doc");
while ((len = buffer.read(b, 0, 1024)) != -1) {
bytcount = bytcount + 1024;
out.write(b, 0, len);
}
out.flush();
//out.close();
//buffer.close();
} catch (IOException e) {
System.out.println("Ocorreu um erro no recebimento do arquivo");
}
}
response:
private void reponse() {
try {
OutputStream out = socket.getOutputStream();
InputStream in = new FileInputStream(pdf);
BufferedInputStream buffer = new BufferedInputStream(in, 1024);
byte[] b = new byte[1024];
int len = 0;
int bytcount = 1024;
int i = 0;
while ((len = buffer.read(b, 0, 1024)) != -1) {
bytcount = bytcount + 1024;
out.write(b, 0, len);
}
out.flush();
out.close();
buffer.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
my client:
public static void main(String[] args) throws Exception {
try {
Socket client = new Socket("127.0.0.1", 5000);
OutputStream out = client.getOutputStream();
InputStream in = new FileInputStream("C:\\autistmo.docx");
BufferedInputStream buffer = new BufferedInputStream(in, 1024);
byte[] b = new byte[1024];
int len = 0;
int bytcount = 1024;
while ((len = buffer.read(b, 0, 1024)) != -1) {
bytcount = bytcount + 1024;
out.write(b, 0, len);
}
// resposta
BufferedInputStream buffer2 = new BufferedInputStream(in, 1024);
FileOutputStream out2 = new FileOutputStream("docs/final.doc");
while ((len = buffer2.read(b, 0, 1024)) != -1) {
bytcount = bytcount + 1024;
out2.write(b, 0, len);
}
out2.close();
buffer2.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
run method:
#Override
public void run() {
getDocArchive();
converter();
reponse();
}