Jump to content


Check out our Community Blogs

maxsap

Member Since 21 Aug 2008
Offline Last Active May 02 2010 02:52 AM
-----

Topics I've Started

converting short array to byte array using java on android device.

26 April 2010 - 03:14 AM

Hello all, I am writting an android program and as part of it I am using AudioTrack and AudioRecord to stream into memory raw pcm. The problem is that I would like to use RTP (currently using jlibRTP) and the classes mentioned above use 16 bit samples (short) and jlibRTP supports 8 bit (byte) so I thought of using java's ByteBuffer to do all the derty work of the convertion. The problem is that it doesn't work, any suggestions?
This is used for recording:
// Allocate Recorder and Start Recording…
		int bufferRead = 0;
		int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(), this
				.getChannelConfiguration(), this.getAudioEncoding());
		AudioRecord recordInstance = new AudioRecord(
				MediaRecorder.AudioSource.MIC, this.getFrequency(), this
						.getChannelConfiguration(), this.getAudioEncoding(),
				bufferSize);
		short[] tempBuffer = new short[bufferSize];
		recordInstance.startRecording();
		while (this.isRecording) {
			// Are we paused?
			synchronized (mutex) {
				if (this.isPaused) {
					try {
						mutex.wait(250);
					} catch (InterruptedException e) {
						throw new IllegalStateException("Wait() interrupted!",
								e);
					}
					continue;
				}
			}

			bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
			if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
				throw new IllegalStateException(
						"read() returned AudioRecord.ERROR_INVALID_OPERATION");
			} else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
				throw new IllegalStateException(
						"read() returned AudioRecord.ERROR_BAD_VALUE");
			} else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
				throw new IllegalStateException(
						"read() returned AudioRecord.ERROR_INVALID_OPERATION");
			}
			try {
				int tempint;
				ByteBuffer bb = ByteBuffer.allocate(tempBuffer.length*2);
				bb.order(ByteOrder.LITTLE_ENDIAN);
				for (int idxBuffer = 0; idxBuffer < bufferRead; ++idxBuffer) {
					bb.putShort(idxBuffer,tempBuffer[idxBuffer]);	
//					Log.e("maxsap","------------* COUNTER -> "+idxBuffer+" BUFFER VALUE IN SHORT -> "+ tempBuffer[idxBuffer]+" BYTEBUFFER VALUE -> "+bb.get(idxBuffer)+"*-----------");
					dataOutputStreamInstance.writeByte(bb.get(idxBuffer));
				}
			} catch (IOException e) {
				Log.e("maxsap",e.getLocalizedMessage());
			}

and this is used for convertion and playback:
int musicLength = (int)(file.length()/2);
		  short[] music = new short[musicLength];


		 // try {
		    // Create a DataInputStream to read the audio data back from the saved file.
		    InputStream is;
			try {
				is = new FileInputStream(file);
			
		    Log.d("maxsap", "------------* GETTING INPUT STREAM*-----------");
		    BufferedInputStream bis = new BufferedInputStream(is);
		    Log.d("maxsap", "------------* GETTING BUFFERED INPUT*-----------");
		    DataInputStream dis = new DataInputStream(bis);
		    Log.d("maxsap", "------------* GETTING DATA INPUT*-----------");
		      
		    // Read the file into the music array.
		    int i = 0;
		    Log.d("maxsap", "------------* READING FROM STREAM*-----------");
		    ByteBuffer bb = ByteBuffer.allocate(music.length*2);
			bb.order(ByteOrder.LITTLE_ENDIAN);	
			while (dis.available() > 0) {
//				Log.d("maxsap", "------------* COUNTER -> "+i+" BUFFER VALUE -> "+dis.readByte()+" *-----------");
				Log.d("maxsap","counter->"+i);
				bb.putShort(dis.readByte());
				i++;
			}
		    Log.d("maxsap", "------------* STREAM READED *-----------");
//		    Integer tempint;
//		    for (int x=1, j=0; x<music.length; x+=2, j++){
//				tempint = ((int) music[x])& 0xFF;
//				music[j] = tempint.shortValue();
//				Log.e("maxsap","------------*"+ music[j]+"*-----------");
//			}

		    // Close the input streams.
		    dis.close();     
		    // Create a new AudioTrack object using the same parameters as the AudioRecord
		    // object used to create the file.
		    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
		    		11025, 
		                                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
		                                           AudioFormat.ENCODING_PCM_16BIT, 
		                                           musicLength, 
		                                           AudioTrack.MODE_STREAM);
		    Log.d("maxsap", "------------* audioTrack initialized *-----------");
		    // Start playback
		    audioTrack.play();
		    for(int x=0; x<music.length; x++){
		    	music[i] = bb.getShort(i);
		    	
		    }
		    // Write the music buffer to the AudioTrack object
		    audioTrack.write(music, 0, musicLength);
//		  } catch (Throwable t) {
//		    Log.e("AudioTrack",t.getLocalizedMessage());
//		  }
			} catch (FileNotFoundException ex) {
				Log.e("maxsap", "------------* FileNotFoundException *-----------");
			} catch (IOException e) {
				Log.e("maxsap", "------------* IOException *-----------");
			} catch(RuntimeException run){
				Log.e("maxsap", "------------* RuntimeException *-----------");
				Log.e("maxsap", "------------* Caused By: "+run.getMessage()+" *-----------");
			}
		}

Note that the arguments for audioTrack and AudioRecord are:
frequency:11025
ChannelConfiguration:AudioFormat.CHANNEL_CONFIGURATION_MONO
audioEncoding : AudioFormat.ENCODING_PCM_16BIT
also there is a known bug in those classes and can't use directly 8 bit configuration.
thanks in advanced maxsap.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download