2012-06-07 2 views
2

AudioRecord 클래스를 사용하여 오디오를 녹음하고 SD 카드에 저장하는 앱이 있습니다. 새로운 HTC One 휴대폰 시리즈 사용자는 녹음 할 수 없습니다.새로운 HTC One 시리즈 Android 휴대 전화가있는 AudioRecord

녹음이 시작되면 1kb 파일이 SD 카드에 저장되고 녹음이 중지됩니다. 일반적으로 적어도 44KB 헤더를 생성하므로 prepare() 함수의 어딘가에서 멈추고 있다고 생각합니다. 나는 이것을 시험해 볼 HTC를 가지고 있지 않기 때문에 나는 어리 석다. 녹음 할 때 사용하는 클래스를 연결했고 압축되지 않은 오디오를 녹음하고 있습니다.

extAudioRecorder = new ExtAudioRecorder(true, 
AudioSource.MIC, 
44100, 
AudioFormat.CHANNEL_IN_MONO, 
AudioFormat.ENCODING_PCM_16BIT); 

나는이 새로운 휴대 전화에서 작동한다고 생각 다음과 같이 내 기록 활동에서, 나는 consturctor으로 extAudioRecorder 객체를 초기화합니다.

도움을 주시면 감사하겠습니다. 녹음을 위해 사용하는 클래스의 전체 소스는 다음과 같습니다. 그것은 또한 LG 옵티 머스 원폰과 같은 일을하고있을 수 있습니다. 모든 값을 시도하는이 코드를 사용하여
AudioSource.MIC
44100
AudioFormat.CHANNEL_IN_MONO
AudioFormat.ENCODING_PCM_16BIT

:

public class ExtAudioRecorder implements Runnable 
{ 
private final static int[] sampleRates = {44100, 22050, 11025, 8000}; 
private static final String AUDIO_RECORDER_FOLDER = "FOLDER"; 
String sdPath = Environment.getExternalStorageDirectory().getPath(); 
File file = new File(sdPath,AUDIO_RECORDER_FOLDER); 
String FullFilePath; 
String fileName; 
static int sampleRate; 
private volatile boolean recording = false; 
double RecordReadDelayInSeconds = 0; 
double RecordDelayInSeconds = 0; 


private MediaPlayer mPlayer; 
private static String mp3Path = Environment.getExternalStorageDirectory() + "/FOLDER/tmp/tmp.mp3"; 


double beatDelayInSeconds = 0; 

public ExtAudioRecorder getInstanse(Boolean recordingCompressed) 
{ 
    ExtAudioRecorder result = null; 

    if(recordingCompressed) 
    { 
     result = new ExtAudioRecorder( false, 
             AudioSource.MIC, 
             sampleRates[3], 
             AudioFormat.CHANNEL_IN_MONO, 
             AudioFormat.ENCODING_PCM_16BIT); 
    } 
    else 
    { 
     int i=0; 
     do 
     { 
      result = new ExtAudioRecorder( true, 
              AudioSource.MIC, 
              sampleRates[i], 
              AudioFormat.CHANNEL_IN_MONO, 
              AudioFormat.ENCODING_PCM_16BIT); 
      sampleRate = sampleRates[i]; 

     } while((++i<sampleRates.length) & !(result.getState() == ExtAudioRecorder.State.INITIALIZING)); 
    } 
    return result; 
} 

/** 
* INITIALIZING : recorder is initializing; 
* READY : recorder has been initialized, recorder not yet started 
* RECORDING : recording 
* ERROR : reconstruction needed 
* STOPPED: reset needed 
*/ 
public enum State {INITIALIZING, READY, RECORDING, ERROR, STOPPED}; 

public static final boolean RECORDING_UNCOMPRESSED = true; 
public static final boolean RECORDING_COMPRESSED = false; 

// The interval in which the recorded samples are output to the file 
// Used only in uncompressed mode 
private static final int TIMER_INTERVAL = 120; 

// Toggles uncompressed recording on/off; RECORDING_UNCOMPRESSED/RECORDING_COMPRESSED 
private boolean   rUncompressed; 

// Recorder used for uncompressed recording 
private AudioRecord  audioRecorder = null; 

// Recorder used for compressed recording 
private MediaRecorder mediaRecorder = null; 

// Stores current amplitude (only in uncompressed mode) 
private int    cAmplitude= 0; 

// Output file path 
private String   filePath = null; 

// Recorder state; see State 
private State   state; 

// File writer (only in uncompressed mode) 
private RandomAccessFile randomAccessWriter; 

// Number of channels, sample rate, sample size(size in bits), buffer size, audio source, sample size(see AudioFormat) 
private short     nChannels; 
private int      sRate; 
private short     bSamples; 
private int      bufferSize; 
private int      aSource; 
private int      aFormat; 

// Number of frames written to file on each output(only in uncompressed mode) 
private int      framePeriod; 

// Buffer for output(only in uncompressed mode) 
private byte[]     buffer; 

// Number of bytes written to file after header(only in uncompressed mode) 
// after stop() is called, this size is written to the header/data chunk in the wave file 
private int      payloadSize; 

/** 
* 
* Returns the state of the recorder in a RehearsalAudioRecord.State typed object. 
* Useful, as no exceptions are thrown. 
* 
* @return recorder state 
*/ 
public State getState() 
{ 
    return state; 
} 

/* 
* 
* Method used for recording. 
* 
*/ 
private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener() 
{ 
    @Override 
    public void onPeriodicNotification(AudioRecord recorder) 
    { 
     if (state != State.STOPPED) 
     { 
     audioRecorder.read(buffer, 0, buffer.length); // Fill buffer 
     try 
     { 
      randomAccessWriter.write(buffer); // Write buffer to file 
      payloadSize += buffer.length; 
      if (bSamples == 16) 
      { 
       for (int i=0; i<buffer.length/2; i++) 
       { // 16bit sample size 
        short curSample = getShort(buffer[i*2], buffer[i*2+1]); 
        if (curSample > cAmplitude) 
        { // Check amplitude 
         cAmplitude = curSample; 
        } 
       } 
      } 
      else  
      { // 8bit sample size 
       for (int i=0; i<buffer.length; i++) 
       { 
        if (buffer[i] > cAmplitude) 
        { // Check amplitude 
         cAmplitude = buffer[i]; 
        } 
       } 
      } 
     } 
     catch (IOException e) 
     { 
      Log.e(ExtAudioRecorder.class.getName(), "Error occured in updateListener, recording is aborted"); 
      stop(); 
     } 
     } 
    } 

    @Override 
    public void onMarkerReached(AudioRecord recorder) 
    { 
     // NOT USED 
    } 
}; 
/** 
* 
* 
* Default constructor 
* 
* Instantiates a new recorder, in case of compressed recording the parameters can be left as 0. 
* In case of errors, no exception is thrown, but the state is set to ERROR 
* 
*/ 
public ExtAudioRecorder(boolean uncompressed, int audioSource, int sampleRate, int channelConfig, int audioFormat) 
{ 
    try 
    { 
     rUncompressed = uncompressed; 
     if (rUncompressed) 
     { // RECORDING_UNCOMPRESSED 
      if (audioFormat == AudioFormat.ENCODING_PCM_16BIT) 
      { 
       bSamples = 16; 
      } 
      else 
      { 
       bSamples = 8; 
      } 

      if (channelConfig == AudioFormat.CHANNEL_IN_MONO) 
      { 
       nChannels = 1; 
      } 
      else 
      { 
       nChannels = 2; 
      } 

      aSource = audioSource; 
      sRate = sampleRate; 
      aFormat = audioFormat; 

      framePeriod = sampleRate * TIMER_INTERVAL/1000; 
      bufferSize = framePeriod * 2 * bSamples * nChannels/8; 
      if (bufferSize < AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat)) 
      { // Check to make sure buffer size is not smaller than the smallest allowed one 
       bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); 
       // Set frame period and timer interval accordingly 
       framePeriod = bufferSize/(2 * bSamples * nChannels/8); 
       Log.w(ExtAudioRecorder.class.getName(), "Increasing buffer size to " + Integer.toString(bufferSize)); 
      } 

      audioRecorder = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSize); 

      if (audioRecorder.getState() != AudioRecord.STATE_INITIALIZED) 
       throw new Exception("AudioRecord initialization failed"); 
      audioRecorder.setRecordPositionUpdateListener(updateListener); 
      audioRecorder.setPositionNotificationPeriod(framePeriod); 
     } else 
     { // RECORDING_COMPRESSED 
      mediaRecorder = new MediaRecorder(); 
      mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
      mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
      mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);    
     } 
     cAmplitude = 0; 
     filePath = null; 
     state = State.INITIALIZING; 
    } catch (Exception e) 
    { 
     if (e.getMessage() != null) 
     { 
      Log.e(ExtAudioRecorder.class.getName(), e.getMessage()); 
     } 
     else 
     { 
      Log.e(ExtAudioRecorder.class.getName(), "Unknown error occured while initializing recording"); 
     } 
     state = State.ERROR; 
    } 
} 

/** 
* Sets output file path, call directly after construction/reset. 
* 
* @param output file path 
* 
*/ 
public void setOutputFile(String argPath) 
{ 

    try 
    { 
     if (state == State.INITIALIZING) 
     { 
      filePath = argPath; 
      if (!rUncompressed) 
      { 
       mediaRecorder.setOutputFile(sdPath + "/FOLDER/" + filePath);      
      } 
     } 
    } 
    catch (Exception e) 
    { 
     if (e.getMessage() != null) 
     { 
      Log.e(ExtAudioRecorder.class.getName(), e.getMessage()); 
     } 
     else 
     { 
      Log.e(ExtAudioRecorder.class.getName(), "Unknown error occured while setting output path"); 
     } 
     state = State.ERROR; 
    } 
} 

/** 
* 
* Returns the largest amplitude sampled since the last call to this method. 
* 
* @return returns the largest amplitude since the last call, or 0 when not in recording state. 
* 
*/ 
public int getMaxAmplitude() 
{ 
    if (state == State.RECORDING) 
    { 
     if (rUncompressed) 
     { 
      int result = cAmplitude; 
      cAmplitude = 0; 
      return result; 
     } 
     else 
     { 
      try 
      { 
       return mediaRecorder.getMaxAmplitude(); 
      } 
      catch (IllegalStateException e) 
      { 
       return 0; 
      } 
     } 
    } 
    else 
    { 
     return 0; 
    } 
} 


/** 
* 
* Prepares the recorder for recording, in case the recorder is not in the INITIALIZING state and the file path was not set 
* the recorder is set to the ERROR state, which makes a reconstruction necessary. 
* In case uncompressed recording is toggled, the header of the wave file is written. 
* In case of an exception, the state is changed to ERROR 
*  
*/ 
public void prepare() 
{ 
    try 
    { 
     if (state == State.INITIALIZING) 
     { 
      if (rUncompressed) 
      { 
       if ((audioRecorder.getState() == AudioRecord.STATE_INITIALIZED) & (filePath != null)) 
       { 
        // write file header 

         if(!file.exists()) 
          file.mkdirs(); 

        fileName = filePath; 
        FullFilePath = file.getAbsoluteFile() + "/" + fileName; 
        randomAccessWriter = new RandomAccessFile(FullFilePath, "rw"); 

        randomAccessWriter.setLength(0); // Set file length to 0, to prevent unexpected behavior in case the file already existed 
        randomAccessWriter.writeBytes("RIFF"); 
        randomAccessWriter.writeInt(0); // Final file size not known yet, write 0 
        randomAccessWriter.writeBytes("WAVE"); 
        randomAccessWriter.writeBytes("fmt "); 
        randomAccessWriter.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM 
        randomAccessWriter.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM 
        randomAccessWriter.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo 
        randomAccessWriter.writeInt(Integer.reverseBytes(sRate)); // Sample rate 
        randomAccessWriter.writeInt(Integer.reverseBytes(sRate*bSamples*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8 
        randomAccessWriter.writeShort(Short.reverseBytes((short)(nChannels*bSamples/8))); // Block align, NumberOfChannels*BitsPerSample/8 
        randomAccessWriter.writeShort(Short.reverseBytes(bSamples)); // Bits per sample 
        randomAccessWriter.writeBytes("data"); 
        randomAccessWriter.writeInt(0); // Data chunk size not known yet, write 0 

        buffer = new byte[framePeriod*bSamples/8*nChannels]; 
        state = State.READY; 
       } 
       else 
       { 
        Log.e(ExtAudioRecorder.class.getName(), "prepare() method called on uninitialized recorder"); 
        state = State.ERROR; 
       } 
      } 
      else 
      { 
       mediaRecorder.prepare(); 
       state = State.READY; 
      } 
     } 
     else 
     { 
      Log.e(ExtAudioRecorder.class.getName(), "prepare() method called on illegal state"); 
      release(); 
      state = State.ERROR; 
     } 
    } 
    catch(Exception e) 
    { 
     if (e.getMessage() != null) 
     { 
      Log.e(ExtAudioRecorder.class.getName(), e.getMessage()); 
     } 
     else 
     { 
      Log.e(ExtAudioRecorder.class.getName(), "Unknown error occured in prepare()"); 
     } 
     state = State.ERROR; 
    } 
} 

/** 
* 
* 
* Releases the resources associated with this class, and removes the unnecessary files, when necessary 
* 
*/ 
public void release() 
{ 
    if (state == State.RECORDING) 
    { 
     stop(); 
    } 
    else 
    { 
     if ((state == State.READY) & (rUncompressed)) 
     { 
      try 
      { 
       randomAccessWriter.close(); // Remove prepared file 
      } 
      catch (IOException e) 
      { 
       Log.e(ExtAudioRecorder.class.getName(), "I/O exception occured while closing output file"); 
      } 
      //delete file 
      //(new File(filePath)).delete(); 
     } 
    } 

    if (rUncompressed) 
    { 
     if (audioRecorder != null) 
     { 
      audioRecorder.release(); 
     } 
    } 
    else 
    { 
     if (mediaRecorder != null) 
     { 
      mediaRecorder.release(); 
     } 
    } 
} 

/** 
* 
* 
* Resets the recorder to the INITIALIZING state, as if it was just created. 
* In case the class was in RECORDING state, the recording is stopped. 
* In case of exceptions the class is set to the ERROR state. 
* 
*/ 
public void reset() 
{ 
    try 
    { 
     if (state != State.ERROR) 
     { 
      release(); 
      filePath = null; // Reset file path 
      cAmplitude = 0; // Reset amplitude 
      if (rUncompressed) 
      { 
       audioRecorder = new AudioRecord(aSource, sRate, nChannels+1, aFormat, bufferSize); 
      } 
      else 
      { 
       mediaRecorder = new MediaRecorder(); 
       mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
       mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
       mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
      } 
      state = State.INITIALIZING; 
     } 
    } 
    catch (Exception e) 
    { 
     Log.e(ExtAudioRecorder.class.getName(), e.getMessage()); 
     state = State.ERROR; 
    } 
} 

/** 
* 
* 
* Starts the recording, and sets the state to RECORDING. 
* Call after prepare(). 
* 
*/ 
public void start() 
{ 
    if (state == State.READY) 
    { 
     if (rUncompressed) 
     { 
      payloadSize = 0; 
      RecordReadDelayInSeconds = 0; 
      RecordDelayInSeconds = 0; 

      mPlayer = new MediaPlayer(); 
      try { 
       mPlayer.setDataSource(mp3Path); 
       mPlayer.prepare(); 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (SecurityException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalStateException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      long recordstarted = System.nanoTime(); 
      audioRecorder.startRecording(); 
      long recordstopped = System.nanoTime(); 
      long recordDelay = recordstopped - recordstarted; 

      double RecordDelayInSeconds = recordDelay/1000000.0; 

      Log.i("StartRecording() Delay in seconds", String.valueOf(RecordDelayInSeconds)); 

      long recordreadstarted = System.nanoTime(); 
      audioRecorder.read(buffer, 0, buffer.length); 
      long recordreadstopped = System.nanoTime(); 
      long recordreadDelay = recordreadstopped - recordreadstarted; 
      RecordReadDelayInSeconds = recordreadDelay/1000000.0; 
      Log.i("Record read() Delay in seconds", String.valueOf(RecordReadDelayInSeconds)); 


      long mediastarted = System.nanoTime(); 
      mPlayer.start(); 
      long mediastopped = System.nanoTime(); 
      long beatDelay = mediastopped - mediastarted; 

      beatDelayInSeconds = 0; 
      beatDelayInSeconds = (beatDelay)/1000000000.0; 
      Log.i("Beat Delay in seconds", String.valueOf(beatDelayInSeconds)); 




     } 
     else 
     { 
      mediaRecorder.start(); 
     } 
     state = State.RECORDING; 
    } 
    else 
    { 
     Log.e(ExtAudioRecorder.class.getName(), "start() called on illegal state"); 
     state = State.ERROR; 
    } 
} 

/** 
* 
* 
* Stops the recording, and sets the state to STOPPED. 
* In case of further usage, a reset is needed. 
* Also finalizes the wave file in case of uncompressed recording. 
* 
*/ 
public void stop() 
{ 
    if (state == State.RECORDING) 
    { 
     if (rUncompressed) 
     { 
      audioRecorder.stop(); 

      try 
      { 
       randomAccessWriter.seek(4); // Write size to RIFF header 
       randomAccessWriter.writeInt(Integer.reverseBytes(36+payloadSize)); 

       randomAccessWriter.seek(40); // Write size to Subchunk2Size field 
       randomAccessWriter.writeInt(Integer.reverseBytes(payloadSize)); 

       randomAccessWriter.close(); 

       //mPlayer.stop(); 
      } 
      catch(IOException e) 
      { 
       Log.e(ExtAudioRecorder.class.getName(), "I/O exception occured while closing output file"); 
       state = State.ERROR; 
      } 
     } 
     else 
     { 
      mediaRecorder.stop(); 
     } 
     state = State.STOPPED; 
    } 
    else 
    { 
     Log.e(ExtAudioRecorder.class.getName(), "stop() called on illegal state"); 
     state = State.ERROR; 
    } 
} 

/* 
* 
* Converts a byte[2] to a short, in LITTLE_ENDIAN format 
* 
*/ 
private short getShort(byte argB1, byte argB2) 
{ 
    return (short)(argB1 | (argB2 << 8)); 
} 

public String[] GetFileProperties() 
{ 
    String[] fileProperties = new String[3]; 
    fileProperties[0] = FullFilePath; 
    fileProperties[1] = fileName; 
    fileProperties[2] = Integer.toString(sampleRate); 

    return fileProperties; 
} 

@Override 
public void run() { 
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
    start(); 

} 

public void StopMediaPlayer() 
{ 

    try { 
     mPlayer.stop(); 
    } catch (IllegalStateException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public boolean isRecording() { 
    return recording; 
} 

public int GetSampleRate() 
{ 
    return sampleRate; 
} 

public double GetBeatDelay() 
{ 
    return beatDelayInSeconds; 
} 

public int GetRecordDelay() 
{ 
    return (int)(RecordReadDelayInSeconds +RecordDelayInSeconds); 

} 

}

답변

1

나는 그 값 작업을 얻을 수 있었다 :
https://github.com/lnanek/Misc/tree/master/TestOneXAudioRecord

그것은 (& T AT) 하나 X에이 로그 엔트리 번 X (유럽)를 출력

1,363,210, 그리고 하나의 S (T 모바일)
D/TestOneXAudioRecordActivity (10500) 시도 레이트에서 44100Hz 비트 2 채널 16
D/TestOneXAudioRecordActivity (10500) : I = AudioRecord.getState AudioRecord.STATE_INITIALIZED
/TestOneXAudioRecordActivity (10500) : 초기화 된 가지 audiorecord = [email protected] f0

한순간에 프로그램에서 AudioRecord를 초기화 할 수 없지만 장치를 재부팅하면 작동이 시작됩니다. 나는 다른 프로그램이 마이크를 사용하고 있거나 이전 시도 중 하나가 AudioRecord를 출시하지 않았다고 생각한다. 즉 하드웨어가 바빴다는 것을 의미한다. 따라서 휴대 전화를 다시 시작하고 다른 녹음 앱을 사용하지 않도록하십시오.

+0

나는 이것이라고 생각합니다! 나는 가서 HTC One을 구입했는데 잘 작동했습니다. 아빠가 전화를 다시 시작하도록하십시오. 고맙습니다! – nawlrus

관련 문제