Raw Audio Waveforms from AMR-NR Data? Java?

All your problems with Audio, Video and Images.

Raw Audio Waveforms from AMR-NR Data? Java?

Postby jbs » Tue May 12, 2009 3:08 am

I'm writing, or at least attempting to write, an application that records data from the microphone and does analysis of the waveform in the frequency domain.

From the fine SDK documentation, I've been able to record and playback audio from the microphone. However, the interface provided by MediaPlayer doesn't seem to provide a way of getting the decoded waveform data. The only supported audio/speech codec is AMR-NB; there seems to be sparse support among audio libraries for this format. The only tools for manipulating AMR-NB that I've come across are either the original reference implementations in C or the reference implementation adapted to work in ffmpeg. Neither are that amenable to using in an Android, Java, userland application.

My question is this: is there some way of getting the data I need without having to write my own AMR-NB decoder library?

Thanks,

Joshua Shaffer
jbs
Freshman
Freshman
 
Posts: 6
Joined: Tue May 12, 2009 2:52 am

Top

Postby jbs » Wed May 13, 2009 9:12 pm

It seems that android.media.AudioRecord allows one to get PCM audio directly from the microphone. However, this is a new feature in 1.5.
jbs
Freshman
Freshman
 
Posts: 6
Joined: Tue May 12, 2009 2:52 am

Postby jbs » Thu May 14, 2009 10:17 pm

So I'm following the SDK documentation for import android.media.AudioRecord and I wrote a simple bit of code that records a PCM audio from the microphone to a file on the SD card.

When audioEncoding = AudioFormat.ENCODING_PCM_8BIT, I get an error when I try to instantiate AudioRecorder that informs me that the buffer size is illegal. This is unlikely the case since I'm using the minimum buffer size as reported by AudioFormat. When audioEncoding = AudioFormat.ENCODING_PCM_8BIT, the only thing that happens is I get a message with the tag "AudioHardwareMSM72XX" that it "Cannot set audpre parameters" and "Cannot enable audpre."

Anyone? Bueller?

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package com.jbs36.AudioRecorderPCM;
  3.  
  4.  
  5.  
  6. import java.io.BufferedOutputStream;
  7.  
  8. import java.io.File;
  9.  
  10. import java.io.FileNotFoundException;
  11.  
  12. import java.io.FileOutputStream;
  13.  
  14. import java.io.IOException;
  15.  
  16. import android.media.AudioFormat;
  17.  
  18. import android.media.AudioRecord;
  19.  
  20. import android.media.MediaRecorder;
  21.  
  22.  
  23.  
  24. public class Recorder implements Runnable {
  25.  
  26.         private int frequency;
  27.  
  28.         private int channelConfiguration;
  29.  
  30.         private volatile boolean isPaused;
  31.  
  32.         private File fileName;
  33.  
  34.         private volatile boolean isRecording;
  35.  
  36.         private final Object mutex = new Object();
  37.  
  38.  
  39.  
  40.         // Changing the sample resolution changes sample type. byte vs. short.
  41.  
  42.         private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
  43.  
  44.  
  45.  
  46.         /**
  47.  
  48.          *
  49.  
  50.          */
  51.  
  52.         public Recorder() {
  53.  
  54.                 super();
  55.  
  56.                 this.setFrequency(8000);
  57.  
  58.                 this.setChannelConfiguration(AudioFormat.CHANNEL_CONFIGURATION_MONO);
  59.  
  60.                 this.setPaused(false);
  61.  
  62.         }
  63.  
  64.  
  65.  
  66.         public void run() {
  67.  
  68.                 // Wait until we're recording...
  69.  
  70.                 synchronized (mutex) {
  71.  
  72.                         while (!this.isRecording) {
  73.  
  74.                                 try {
  75.  
  76.                                         mutex.wait();
  77.  
  78.                                 } catch (InterruptedException e) {
  79.  
  80.                                         throw new IllegalStateException("Wait() interrupted!", e);
  81.  
  82.                                 }
  83.  
  84.                         }
  85.  
  86.                 }
  87.  
  88.  
  89.  
  90.                 // Open output stream...
  91.  
  92.                 if (this.fileName == null) {
  93.  
  94.                         throw new IllegalStateException("fileName is null");
  95.  
  96.                 }
  97.  
  98.                 java.io.BufferedOutputStream bufferedStreamInstance = null;
  99.  
  100.                 if (fileName.exists()) {
  101.  
  102.                         fileName.delete();
  103.  
  104.                 }
  105.  
  106.                 try {
  107.  
  108.                         fileName.createNewFile();
  109.  
  110.                 } catch (IOException e) {
  111.  
  112.                         throw new IllegalStateException("Cannot create file: " + fileName.toString());
  113.  
  114.                 }
  115.  
  116.                 try {
  117.  
  118.                         bufferedStreamInstance = new BufferedOutputStream(
  119.  
  120.                                         new FileOutputStream(this.fileName));
  121.  
  122.                 } catch (FileNotFoundException e) {
  123.  
  124.                         throw new IllegalStateException("Cannot Open File", e);
  125.  
  126.                 }
  127.  
  128.  
  129.  
  130.                 // We're important...
  131.  
  132.                 android.os.Process
  133.  
  134.                                 .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
  135.  
  136.  
  137.  
  138.                 // Allocate Recorder and Start Recording...
  139.  
  140.                 int bufferRead = 0;
  141.  
  142.                 int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(),
  143.  
  144.                                 this.getChannelConfiguration(), this.getAudioEncoding());
  145.  
  146.                 AudioRecord recordInstance = new AudioRecord(
  147.  
  148.                                 MediaRecorder.AudioSource.MIC, this.getFrequency(), this
  149.  
  150.                                                 .getChannelConfiguration(), this.getAudioEncoding(),
  151.  
  152.                                 bufferSize);
  153.  
  154.                 byte[] tempBuffer = new byte[bufferSize];
  155.  
  156.                 recordInstance.startRecording();
  157.  
  158.                 while (this.isRecording) {
  159.  
  160.  
  161.  
  162.                         // Are we paused?
  163.  
  164.                         synchronized (mutex) {
  165.  
  166.                                 if (this.isPaused) {
  167.  
  168.                                         try {
  169.  
  170.                                                 mutex.wait(250);
  171.  
  172.                                         } catch (InterruptedException e) {
  173.  
  174.                                                 throw new IllegalStateException("Wait() interrupted!",
  175.  
  176.                                                                 e);
  177.  
  178.                                         }
  179.  
  180.                                         continue;
  181.  
  182.                                 }
  183.  
  184.                         }
  185.  
  186.  
  187.  
  188.                         bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
  189.  
  190.                         if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
  191.  
  192.                                 throw new IllegalStateException(
  193.  
  194.                                                 "read() returned AudioRecord.ERROR_INVALID_OPERATION");
  195.  
  196.                         } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
  197.  
  198.                                 throw new IllegalStateException(
  199.  
  200.                                                 "read() returned AudioRecord.ERROR_BAD_VALUE");
  201.  
  202.                         } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
  203.  
  204.                                 throw new IllegalStateException(
  205.  
  206.                                                 "read() returned AudioRecord.ERROR_INVALID_OPERATION");
  207.  
  208.                         }
  209.  
  210.  
  211.  
  212.                         try {
  213.  
  214.                                 bufferedStreamInstance.write(tempBuffer, 0, bufferRead);
  215.  
  216.                         } catch (IOException e) {
  217.  
  218.                                 throw new IllegalStateException(
  219.  
  220.                                                 "IO Error while writing to output file.", e);
  221.  
  222.                         }
  223.  
  224.                 }
  225.  
  226.  
  227.  
  228.                 // Close resources...
  229.  
  230.                 recordInstance.startRecording();
  231.  
  232.                 try {
  233.  
  234.                         bufferedStreamInstance.close();
  235.  
  236.                 } catch (IOException e) {
  237.  
  238.                         throw new IllegalStateException("Cannot close buffered writer.");
  239.  
  240.                 }
  241.  
  242.         }
  243.  
  244.  
  245.  
  246.         public void setFileName(File fileName) {
  247.  
  248.                 this.fileName = fileName;
  249.  
  250.         }
  251.  
  252.  
  253.  
  254.         public File getFileName() {
  255.  
  256.                 return fileName;
  257.  
  258.         }
  259.  
  260.  
  261.  
  262.         /**
  263.  
  264.          * @param isRecording
  265.  
  266.          *            the isRecording to set
  267.  
  268.          */
  269.  
  270.         public void setRecording(boolean isRecording) {
  271.  
  272.                 synchronized (mutex) {
  273.  
  274.                         this.isRecording = isRecording;
  275.  
  276.                         if (this.isRecording) {
  277.  
  278.                                 mutex.notify();
  279.  
  280.                         }
  281.  
  282.                 }
  283.  
  284.         }
  285.  
  286.  
  287.  
  288.         /**
  289.  
  290.          * @return the isRecording
  291.  
  292.          */
  293.  
  294.         public boolean isRecording() {
  295.  
  296.                 synchronized (mutex) {
  297.  
  298.                         return isRecording;
  299.  
  300.                 }
  301.  
  302.         }
  303.  
  304.  
  305.  
  306.         /**
  307.  
  308.          * @param frequency
  309.  
  310.          *            the frequency to set
  311.  
  312.          */
  313.  
  314.         public void setFrequency(int frequency) {
  315.  
  316.                 this.frequency = frequency;
  317.  
  318.         }
  319.  
  320.  
  321.  
  322.         /**
  323.  
  324.          * @return the frequency
  325.  
  326.          */
  327.  
  328.         public int getFrequency() {
  329.  
  330.                 return frequency;
  331.  
  332.         }
  333.  
  334.  
  335.  
  336.         /**
  337.  
  338.          * @param channelConfiguration
  339.  
  340.          *            the channelConfiguration to set
  341.  
  342.          */
  343.  
  344.         public void setChannelConfiguration(int channelConfiguration) {
  345.  
  346.                 this.channelConfiguration = channelConfiguration;
  347.  
  348.         }
  349.  
  350.  
  351.  
  352.         /**
  353.  
  354.          * @return the channelConfiguration
  355.  
  356.          */
  357.  
  358.         public int getChannelConfiguration() {
  359.  
  360.                 return channelConfiguration;
  361.  
  362.         }
  363.  
  364.  
  365.  
  366.         /**
  367.  
  368.          * @return the audioEncoding
  369.  
  370.          */
  371.  
  372.         public int getAudioEncoding() {
  373.  
  374.                 return audioEncoding;
  375.  
  376.         }
  377.  
  378.  
  379.  
  380.         /**
  381.  
  382.          * @param isPaused
  383.  
  384.          *            the isPaused to set
  385.  
  386.          */
  387.  
  388.         public void setPaused(boolean isPaused) {
  389.  
  390.                 synchronized (mutex) {
  391.  
  392.                         this.isPaused = isPaused;
  393.  
  394.                 }
  395.  
  396.         }
  397.  
  398.  
  399.  
  400.         /**
  401.  
  402.          * @return the isPaused
  403.  
  404.          */
  405.  
  406.         public boolean isPaused() {
  407.  
  408.                 synchronized (mutex) {
  409.  
  410.                         return isPaused;
  411.  
  412.                 }
  413.  
  414.         }
  415.  
  416.  
  417.  
  418. }
  419.  
  420.  
Parsed in 0.052 seconds, using GeSHi 1.0.8.4
jbs
Freshman
Freshman
 
Posts: 6
Joined: Tue May 12, 2009 2:52 am

Postby jbs » Fri May 15, 2009 6:38 am

Okay. It works now. It turns out that the audio device stopped responding after the Music application, for lack of a more precise description, wonked-out; a reboot restored the audio device to a functional state.

After playing with the the code I have,

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. import java.io.BufferedOutputStream;
  5.  
  6. import java.io.DataOutputStream;
  7.  
  8. import java.io.File;
  9.  
  10. import java.io.FileNotFoundException;
  11.  
  12. import java.io.FileOutputStream;
  13.  
  14. import java.io.IOException;
  15.  
  16. import android.media.AudioFormat;
  17.  
  18. import android.media.AudioRecord;
  19.  
  20. import android.media.MediaRecorder;
  21.  
  22.  
  23.  
  24.  
  25.  
  26. public class Recorder implements Runnable {
  27.  
  28.         private int frequency;
  29.  
  30.         private int channelConfiguration;
  31.  
  32.         private volatile boolean isPaused;
  33.  
  34.         private File fileName;
  35.  
  36.         private volatile boolean isRecording;
  37.  
  38.         private final Object mutex = new Object();
  39.  
  40.  
  41.  
  42.         // Changing the sample resolution changes sample type. byte vs. short.
  43.  
  44.         private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
  45.  
  46.  
  47.  
  48.         /**
  49.  
  50.          *
  51.  
  52.          */
  53.  
  54.         public Recorder() {
  55.  
  56.                 super();
  57.  
  58.                 this.setFrequency(11025);
  59.  
  60.                 this.setChannelConfiguration(AudioFormat.CHANNEL_CONFIGURATION_MONO);
  61.  
  62.                 this.setPaused(false);
  63.  
  64.         }
  65.  
  66.  
  67.  
  68.         public void run() {
  69.  
  70.                 // Wait until we're recording...
  71.  
  72.                 synchronized (mutex) {
  73.  
  74.                         while (!this.isRecording) {
  75.  
  76.                                 try {
  77.  
  78.                                         mutex.wait();
  79.  
  80.                                 } catch (InterruptedException e) {
  81.  
  82.                                         throw new IllegalStateException("Wait() interrupted!", e);
  83.  
  84.                                 }
  85.  
  86.                         }
  87.  
  88.                 }
  89.  
  90.  
  91.  
  92.                 // Open output stream...
  93.  
  94.                 if (this.fileName == null) {
  95.  
  96.                         throw new IllegalStateException("fileName is null");
  97.  
  98.                 }
  99.  
  100.                 BufferedOutputStream bufferedStreamInstance = null;
  101.  
  102.                 if (fileName.exists()) {
  103.  
  104.                         fileName.delete();
  105.  
  106.                 }
  107.  
  108.                 try {
  109.  
  110.                         fileName.createNewFile();
  111.  
  112.                 } catch (IOException e) {
  113.  
  114.                         throw new IllegalStateException("Cannot create file: " + fileName.toString());
  115.  
  116.                 }
  117.  
  118.                 try {
  119.  
  120.                         bufferedStreamInstance = new BufferedOutputStream(
  121.  
  122.                                         new FileOutputStream(this.fileName));
  123.  
  124.                 } catch (FileNotFoundException e) {
  125.  
  126.                         throw new IllegalStateException("Cannot Open File", e);
  127.  
  128.                 }
  129.  
  130.                 DataOutputStream dataOutputStreamInstance =
  131.  
  132.                         new DataOutputStream(bufferedStreamInstance);
  133.  
  134.                
  135.  
  136.                 // We're important...
  137.  
  138.                 android.os.Process
  139.  
  140.                                 .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
  141.  
  142.  
  143.  
  144.                 // Allocate Recorder and Start Recording...
  145.  
  146.                 int bufferRead = 0;
  147.  
  148.                 int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(),
  149.  
  150.                                 this.getChannelConfiguration(), this.getAudioEncoding());
  151.  
  152.                 AudioRecord recordInstance = new AudioRecord(
  153.  
  154.                                 MediaRecorder.AudioSource.MIC, this.getFrequency(), this
  155.  
  156.                                                 .getChannelConfiguration(), this.getAudioEncoding(),
  157.  
  158.                                 bufferSize);
  159.  
  160.                 short[] tempBuffer = new short[bufferSize];
  161.  
  162.                 recordInstance.startRecording();
  163.  
  164.                 while (this.isRecording) {
  165.  
  166.                         // Are we paused?
  167.  
  168.                         synchronized (mutex) {
  169.  
  170.                                 if (this.isPaused) {
  171.  
  172.                                         try {
  173.  
  174.                                                 mutex.wait(250);
  175.  
  176.                                         } catch (InterruptedException e) {
  177.  
  178.                                                 throw new IllegalStateException("Wait() interrupted!",
  179.  
  180.                                                                 e);
  181.  
  182.                                         }
  183.  
  184.                                         continue;
  185.  
  186.                                 }
  187.  
  188.                         }
  189.  
  190.                        
  191.  
  192.                         bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
  193.  
  194.                         if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
  195.  
  196.                                 throw new IllegalStateException(
  197.  
  198.                                                 "read() returned AudioRecord.ERROR_INVALID_OPERATION");
  199.  
  200.                         } else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
  201.  
  202.                                 throw new IllegalStateException(
  203.  
  204.                                                 "read() returned AudioRecord.ERROR_BAD_VALUE");
  205.  
  206.                         } else if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
  207.  
  208.                                 throw new IllegalStateException(
  209.  
  210.                                                 "read() returned AudioRecord.ERROR_INVALID_OPERATION");
  211.  
  212.                         }
  213.  
  214.                         try {
  215.  
  216.                                 for (int idxBuffer = 0; idxBuffer < bufferRead; ++idxBuffer) {
  217.  
  218.                                         dataOutputStreamInstance.writeShort(tempBuffer[idxBuffer]);
  219.  
  220.                                 }
  221.  
  222.                         } catch (IOException e) {
  223.  
  224.                                 throw new IllegalStateException(
  225.  
  226.                                         "dataOutputStreamInstance.writeShort(curVal)");
  227.  
  228.                         }
  229.  
  230.                        
  231.  
  232.                 }
  233.  
  234.  
  235.  
  236.                 // Close resources...
  237.  
  238.                 recordInstance.stop();
  239.  
  240.                 try {
  241.  
  242.                         bufferedStreamInstance.close();
  243.  
  244.                 } catch (IOException e) {
  245.  
  246.                         throw new IllegalStateException("Cannot close buffered writer.");
  247.  
  248.                 }
  249.  
  250.         }
  251.  
  252.  
  253.  
  254.         public void setFileName(File fileName) {
  255.  
  256.                 this.fileName = fileName;
  257.  
  258.         }
  259.  
  260.  
  261.  
  262.         public File getFileName() {
  263.  
  264.                 return fileName;
  265.  
  266.         }
  267.  
  268.  
  269.  
  270.         /**
  271.  
  272.          * @param isRecording
  273.  
  274.          *            the isRecording to set
  275.  
  276.          */
  277.  
  278.         public void setRecording(boolean isRecording) {
  279.  
  280.                 synchronized (mutex) {
  281.  
  282.                         this.isRecording = isRecording;
  283.  
  284.                         if (this.isRecording) {
  285.  
  286.                                 mutex.notify();
  287.  
  288.                         }
  289.  
  290.                 }
  291.  
  292.         }
  293.  
  294.  
  295.  
  296.         /**
  297.  
  298.          * @return the isRecording
  299.  
  300.          */
  301.  
  302.         public boolean isRecording() {
  303.  
  304.                 synchronized (mutex) {
  305.  
  306.                         return isRecording;
  307.  
  308.                 }
  309.  
  310.         }
  311.  
  312.  
  313.  
  314.         /**
  315.  
  316.          * @param frequency
  317.  
  318.          *            the frequency to set
  319.  
  320.          */
  321.  
  322.         public void setFrequency(int frequency) {
  323.  
  324.                 this.frequency = frequency;
  325.  
  326.         }
  327.  
  328.  
  329.  
  330.         /**
  331.  
  332.          * @return the frequency
  333.  
  334.          */
  335.  
  336.         public int getFrequency() {
  337.  
  338.                 return frequency;
  339.  
  340.         }
  341.  
  342.  
  343.  
  344.         /**
  345.  
  346.          * @param channelConfiguration
  347.  
  348.          *            the channelConfiguration to set
  349.  
  350.          */
  351.  
  352.         public void setChannelConfiguration(int channelConfiguration) {
  353.  
  354.                 this.channelConfiguration = channelConfiguration;
  355.  
  356.         }
  357.  
  358.  
  359.  
  360.         /**
  361.  
  362.          * @return the channelConfiguration
  363.  
  364.          */
  365.  
  366.         public int getChannelConfiguration() {
  367.  
  368.                 return channelConfiguration;
  369.  
  370.         }
  371.  
  372.  
  373.  
  374.         /**
  375.  
  376.          * @return the audioEncoding
  377.  
  378.          */
  379.  
  380.         public int getAudioEncoding() {
  381.  
  382.                 return audioEncoding;
  383.  
  384.         }
  385.  
  386.  
  387.  
  388.         /**
  389.  
  390.          * @param isPaused
  391.  
  392.          *            the isPaused to set
  393.  
  394.          */
  395.  
  396.         public void setPaused(boolean isPaused) {
  397.  
  398.                 synchronized (mutex) {
  399.  
  400.                         this.isPaused = isPaused;
  401.  
  402.                 }
  403.  
  404.         }
  405.  
  406.  
  407.  
  408.         /**
  409.  
  410.          * @return the isPaused
  411.  
  412.          */
  413.  
  414.         public boolean isPaused() {
  415.  
  416.                 synchronized (mutex) {
  417.  
  418.                         return isPaused;
  419.  
  420.                 }
  421.  
  422.         }
  423.  
  424.  
  425.  
  426. }
  427.  
  428.  
Parsed in 0.053 seconds, using GeSHi 1.0.8.4


And, I drive that code with:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. public class AudioRecorderPCM extends Activity {
  3.  
  4.         /** Called when the activity is first created. */
  5.  
  6.         @Override
  7.  
  8.         public void onCreate(Bundle savedInstanceState) {
  9.  
  10.                 super.onCreate(savedInstanceState);
  11.  
  12.                 setContentView(R.layout.main);
  13.  
  14.                
  15.  
  16.                 // Record 20 seconds of audio.
  17.  
  18.                 Recorder recorderInstance = new Recorder();
  19.  
  20.                 Thread th = new Thread(recorderInstance);
  21.  
  22.                 recorderInstance.setFileName(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.raw"));
  23.  
  24.                 th.start();
  25.  
  26.                 recorderInstance.setRecording(true);
  27.  
  28.                 synchronized (this) {
  29.  
  30.                 try {
  31.  
  32.                         this.wait(20000);
  33.  
  34.                 } catch (InterruptedException e) {
  35.  
  36.                         e.printStackTrace();
  37.  
  38.                 }
  39.  
  40.                
  41.  
  42.                 }
  43.  
  44.                 recorderInstance.setRecording(false);
  45.  
  46.                 try {
  47.  
  48.                         th.join();
  49.  
  50.                 } catch (InterruptedException e) {
  51.  
  52.                         e.printStackTrace();
  53.  
  54.                 }
  55.  
  56.                
  57.  
  58.                
  59.  
  60.         }
  61.  
  62. }
  63.  
  64.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


This writes a file 'test.raw' to the SDCard. Each sample is a signed, big endian, 16-bit integer. I was able to play it in matlab with wavplay.

Hope this helps anyone else who is trying to get this part of the API to work. This code works on my G1, but is seems as if there is no way to tell what the sampling rate and sample resolution on a given device are. It doesn't seem to throw any errors if you pick a bad combination of parameters; it just fails.
jbs
Freshman
Freshman
 
Posts: 6
Joined: Tue May 12, 2009 2:52 am

Question

Postby sciarro84 » Thu May 21, 2009 4:54 pm

Hi jbs!

I've tried to use your code but I obtain some errors on the class AudioRecorderPCM.
It' says to me that "The public type AudioRecorderPCM must be defined in its own file"...
What I have to do to utilize your code? Cos' until now I just copy and paste your code....
Can you please help me to fix my problem? Sorry if it's a dumb question but I'm really new with Android.

Thank you in advance for your kindness!
Sciarro84
sciarro84
Freshman
Freshman
 
Posts: 5
Joined: Thu May 21, 2009 4:44 pm
Location: Italy

Postby csvy » Mon Jun 08, 2009 1:35 am

Are we allowed to use this sample code you've written in our own programs? Thanks!
csvy
Freshman
Freshman
 
Posts: 2
Joined: Tue Nov 11, 2008 8:56 am

Top

Re: Question

Postby gunnar-medial » Wed Jul 08, 2009 12:17 am

sciarro84 wrote:Hi jbs!

I've tried to use your code but I obtain some errors on the class AudioRecorderPCM.
It' says to me that "The public type AudioRecorderPCM must be defined in its own file"...
What I have to do to utilize your code? Cos' until now I just copy and paste your code....
Can you please help me to fix my problem? Sorry if it's a dumb question but I'm really new with Android.

Thank you in advance for your kindness!
Sciarro84


Classes are typically stored in a file with the same name as the class,
so the code AudioRecorderPCM should go into a file "AudioRecorderPCM.java"
gunnar-medial
Freshman
Freshman
 
Posts: 7
Joined: Sun Jul 05, 2009 9:24 pm
Location: Stockholm, Sweden

Postby johnwoodinfinityphase » Sat Jul 25, 2009 3:16 pm

its not working for me :(
on my G1 phone I am getting following log
messages via adb...

D/AudioHardwareMSM72XX( 35): audpre_index = 0, tx_iir_index = 0
D/HTC Acoustic( 35): msm72xx_enable_audpre: 0x0000
E/AudioRecord( 597): Error obtaining an audio buffer, giving up.

it happens when
startRecording()
is called

any ideas would help me out a lot?
johnwoodinfinityphase
Once Poster
Once Poster
 
Posts: 1
Joined: Sat Jul 25, 2009 3:09 pm

Postby zrgiu » Mon Jul 27, 2009 6:53 pm

I have the same problem as johnwoodinfinityphase . Anybody help ?
zrgiu
Junior Developer
Junior Developer
 
Posts: 10
Joined: Sat Nov 01, 2008 5:54 pm

Postby vf10a » Wed Aug 05, 2009 9:51 am

jbs wrote:This writes a file 'test.raw' to the SDCard. Each sample is a signed, big endian, 16-bit integer. I was able to play it in matlab with wavplay.


Does anyone know what each sample number represents / what unit it is in?
vf10a
Freshman
Freshman
 
Posts: 2
Joined: Tue Jun 16, 2009 4:21 pm

Postby its_neil » Wed Aug 05, 2009 12:19 pm

I'm trying this and not having much luck either. I mean, I can get the raw file onto the SD card but whenever I try and play it I just get a 'bzzzt' noise from the speakers (using my computer or using AudioTrack)

What's going wrong? There doesn't seem to be much support on this at all - I'm suprised the choices we have for audio recording are either crap quality MP3 or this hardly documented AudioRecord without something in the middle.

I'm using AudioTrack to load the recorded audio and play it back, but all I get is a buzz.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.     public void play() {
  3.  
  4.             Log.i("RAW","PLAYING");
  5.  
  6.             AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,AudioRecord.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) ,AudioTrack.MODE_STREAM);
  7.  
  8.                 File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/test.raw");
  9.  
  10.                
  11.  
  12.                 try {
  13.  
  14.                         byte[] song = getBytesFromFile(f);
  15.  
  16.                         at.write(song, 0, song.length);
  17.  
  18.                         at.play();
  19.  
  20.                 } catch (Throwable t) {
  21.  
  22.                         Log.e("RAW","Playback Fail");
  23.  
  24.                 }
  25.  
  26.     }
  27.  
  28.    
  29.  
  30.     public static byte[] getBytesFromFile(File file) throws IOException {
  31.  
  32.         InputStream is = new FileInputStream(file);
  33.  
  34.         long length = file.length();
  35.  
  36.         byte[] bytes = new byte[(int)length];
  37.  
  38.         int offset = 0;
  39.  
  40.         int numRead = 0;
  41.  
  42.         while (offset < bytes.length
  43.  
  44.                && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
  45.  
  46.             offset += numRead;
  47.  
  48.         }
  49.  
  50.         is.close();
  51.  
  52.         return bytes;
  53.  
  54.     }
  55.  
  56.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


Is there something that I'm doing wrong?
its_neil
Freshman
Freshman
 
Posts: 4
Joined: Tue Jun 30, 2009 2:11 pm

Doubt in playing raw file

Postby harshadha » Thu Aug 20, 2009 6:00 am

Hai,

Iam also trying to play the audio file reading from raw file,using the above code.But iam getting Invalid buffer size.
Can you please tell me how to solve it.

Thanks in Advance.


Regards,
Harshadha.
Regards,
Lavanya S.R
harshadha
Freshman
Freshman
 
Posts: 9
Joined: Mon Jan 21, 2008 8:01 am
Location: India

Postby gunnar-medial » Wed Sep 16, 2009 10:59 pm

I found the following permission statement is needed in the manifest :
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
Parsed in 0.000 seconds, using GeSHi 1.0.8.4

else the startRecording() call will fail.
Also if running on a real phone over USB (using on device debugging or running the app) make sure the device SD card is not mounted over USB on your computer since the phone does not have access to the card if so.

Unless you require the detailed access AudioRecord offers then I found this tutorial works:
http://www.benmccann.com/dev-blog/andro ... -tutorial/
gunnar-medial
Freshman
Freshman
 
Posts: 7
Joined: Sun Jul 05, 2009 9:24 pm
Location: Stockholm, Sweden

Postby joejoekale » Sat Oct 10, 2009 5:45 pm

Hi,

I'm trying to look at the values on the short[] buffer created using AudioRecord from the mic.
when I build a graph representing the these values it has no systematic pattern no matter what I record.
am I missing anything ????
maybe in the way the short values should be interpreted (big/small enndian signed/unsigned) ?
joejoekale
Once Poster
Once Poster
 
Posts: 1
Joined: Sat Oct 10, 2009 5:35 pm

Postby dijieming » Fri Oct 16, 2009 3:10 pm

joejoekale: it is most likely endianness mismatch. Same if you hear clicks/static instead of your recorded audio when playing a Android captured pcm file. Ensure you are reading captured files in big-endian. For example, in matlab:

Code: Select all
fid = fopen('test.pcm','r','b');
test_audio = fread(fid,inf,'int16','b');
fclose(fid)
dijieming
Once Poster
Once Poster
 
Posts: 1
Joined: Fri Oct 16, 2009 2:28 pm

Top
Next

Return to Multimedia Problems

Who is online

Users browsing this forum: No registered users and 11 guests