14

Ich entwickle eine Anwendung wie im Gespräch Tom, funktioniert alles gut, nur die Audioaufnahme macht Probleme auf einigen Geräten, Audio funktioniert auch gut auf meinem hdpi Gerät, aber wenn ich es auf Samsung Tab 7 oder Tab 10 oder einem anderen Telefon laufen, auf einigen Geräten hört es kontinuierlich den Ton und auf einigen Geräten überhaupt nicht zu hören, verwende ich folgenden Code für Audio-Aufnahme.Talking App wie im Gespräch Tom, Audio Recording funktionierte nicht auf allen Geräten

private int RECORDER_CHANNELS = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
private int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
private int RECORDER_SAMPLERATE = 44100; 
private byte RECORDER_BPP = (byte) 16; 
private AudioRecord audioRecorder; 
private int detectVoice= 350; 

public class analyzeAudio extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPreExecute() { 
     Log.e("Play", "on Pre"); 

    } 

    @Override 
    protected Void doInBackground(Void... voids) { 

     try { 
      // Get the minimum buffer size required for the successful creation of an AudioRecord object. 
      int bufferSizeInBytes = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
        RECORDER_AUDIO_ENCODING); 

      bufferSizeInBytes = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT); 
      // Initialize Audio Recorder. 
      audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RECORDER_SAMPLERATE, 
        RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSizeInBytes); 

      // Start Recording. 
      audioRecorder.startRecording(); 

      int numberOfReadBytes = 0; 
      byte audioBuffer[] = new byte[bufferSizeInBytes]; 
      boolean recording = false; 
      float tempFloatBuffer[] = new float[3]; 
      int tempIndex = 0; 
      int totalReadBytes = 0; 
      byte totalByteBuffer[] = new byte[60 * 44100 * 2]; 

      // While data come from microphone. 
      boolean isListening = true; 
      while (true) { 
       float totalAbsValue = 0.0f; 
       short sample = 0; 

       numberOfReadBytes = audioRecorder.read(audioBuffer, 0, bufferSizeInBytes); 

       // Analyze Sound. 
       for (int i = 0; i < bufferSizeInBytes; i += 2) { 
        sample = (short) ((audioBuffer[i]) | audioBuffer[i + 1] << 8); 
        totalAbsValue += Math.abs(sample)/(numberOfReadBytes/2); 
       } 

       // Analyze temp buffer. 
       tempFloatBuffer[tempIndex % 3] = totalAbsValue; 
       float temp = 0.0f; 
       for (int i = 0; i < 3; ++i) 
        temp += tempFloatBuffer[i]; 

       if ((temp >= 0 && temp <= detectVoice) && recording == false) { 
        Log.i("TAG", "1"); 
        tempIndex++; 
        continue; 
       } 

       if (temp > detectVoice && recording == false) { 
        Log.i("TAG", "2"); 
        if (isPlaying) { 
         audioRecorder.release(); 
         break; 
        } 
        recording = true; 

        if (isListening) { 
         finishIdleAnimation(); 
         isListening = false; 
         isPlaying = true; 
         currentAnimationId = Constants.animHearout; 
         _index = 0; 
         if (_timer != null) { 
          _timer.cancel(); 
         } 
         _timer = new Timer(); 
         _timer.schedule(new TickClass(), 7, dealyTime(7, 1)); 

        } else { 
         Log.e("Caceling", "Yes + isPlaying" + isPlaying); 
         new analyzeAudio().cancel(true); 
        } 
       } 

       if ((temp >= 0 && temp <= detectVoice) && recording == true) { 
        Log.i("TAG", "Save audio to file."); 

        // Save audio to file. 
        String filepath = Environment.getExternalStorageDirectory().getPath(); 
        File file = new File(filepath, "AudioRecorder"); 
        if (!file.exists()) 
         file.mkdirs(); 

        String fn = file.getAbsolutePath() + "/" + "temp" + ".wav"; 
        long totalAudioLen = 0; 
        long totalDataLen = totalAudioLen + 36; 
        long longSampleRate = RECORDER_SAMPLERATE; 
        int channels = 1; 
        long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; 
        totalAudioLen = totalReadBytes; 
        totalDataLen = totalAudioLen + 36; 
        byte finalBuffer[] = new byte[totalReadBytes + 44]; 

        finalBuffer[0] = 'R'; // RIFF/WAVE header 
        finalBuffer[1] = 'I'; 
        finalBuffer[2] = 'F'; 
        finalBuffer[3] = 'F'; 
        finalBuffer[4] = (byte) (totalDataLen & 0xff); 
        finalBuffer[5] = (byte) ((totalDataLen >> 8) & 0xff); 
        finalBuffer[6] = (byte) ((totalDataLen >> 16) & 0xff); 
        finalBuffer[7] = (byte) ((totalDataLen >> 24) & 0xff); 
        finalBuffer[8] = 'W'; 
        finalBuffer[9] = 'A'; 
        finalBuffer[10] = 'V'; 
        finalBuffer[11] = 'E'; 
        finalBuffer[12] = 'f'; // 'fmt ' chunk 
        finalBuffer[13] = 'm'; 
        finalBuffer[14] = 't'; 
        finalBuffer[15] = ' '; 
        finalBuffer[16] = 16; // 4 bytes: size of 'fmt ' chunk 
        finalBuffer[17] = 0; 
        finalBuffer[18] = 0; 
        finalBuffer[19] = 0; 
        finalBuffer[20] = 1; // format = 1 
        finalBuffer[21] = 0; 
        finalBuffer[22] = (byte) channels; 
        finalBuffer[23] = 0; 
        finalBuffer[24] = (byte) (longSampleRate & 0xff); 
        finalBuffer[25] = (byte) ((longSampleRate >> 8) & 0xff); 
        finalBuffer[26] = (byte) ((longSampleRate >> 16) & 0xff); 
        finalBuffer[27] = (byte) ((longSampleRate >> 24) & 0xff); 
        finalBuffer[28] = (byte) (byteRate & 0xff); 
        finalBuffer[29] = (byte) ((byteRate >> 8) & 0xff); 
        finalBuffer[30] = (byte) ((byteRate >> 16) & 0xff); 
        finalBuffer[31] = (byte) ((byteRate >> 24) & 0xff); 
        finalBuffer[32] = (byte) (2 * 16/8); // block align 
        finalBuffer[33] = 0; 
        finalBuffer[34] = RECORDER_BPP; // bits per sample 
        finalBuffer[35] = 0; 
        finalBuffer[36] = 'd'; 
        finalBuffer[37] = 'a'; 
        finalBuffer[38] = 't'; 
        finalBuffer[39] = 'a'; 
        finalBuffer[40] = (byte) (totalAudioLen & 0xff); 
        finalBuffer[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
        finalBuffer[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
        finalBuffer[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

        for (int i = 0; i < totalReadBytes; ++i) 
         finalBuffer[44 + i] = totalByteBuffer[i]; 

        FileOutputStream out; 
        try { 
         out = new FileOutputStream(fn); 
         try { 
          out.write(finalBuffer); 
          out.close(); 
          isRecorded = true; 
         } catch (IOException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 

        } catch (FileNotFoundException e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 


        tempIndex++; 
        break; 
       } 

       // -> Recording sound here. 
       Log.i("TAG", "Recording Sound."); 
       for (int i = 0; i < numberOfReadBytes; i++) 
        totalByteBuffer[totalReadBytes + i] = audioBuffer[i]; 
       totalReadBytes += numberOfReadBytes; 

       tempIndex++; 
      } 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 

     Log.e("Play", "on POst"); 
     if (isRecorded) { 
      currentAnimationId = Constants.animHearoutend; 
      _index = 8; 
      if (_timer != null) { 
       _timer.cancel(); 
      } 
      _timer = new Timer(); 
      _timer.schedule(new TickClass(), 4, dealyTime(4, 1)); 
      playFromSdCard(); 
     } 
    } 
} 
+0

Auf welchen Geräten scheitert es? haben Sie debuggen oder ein Protokoll von einem fehlerhaften Gerät haben? –

+0

Ich wollte nur wissen, ob Ihr Aufzeichnungsobjekt initialisiert wurde? –

+1

Ja, es ist definitiv, es funktioniert gut für ein HDPI-Gerät, QMobile, aber während ich auf Samsung S4 laufen es hört ständig und hört nicht auf zu hören und für Samsung Tab 2, 7 '' es überhaupt nicht zu hören. –

Antwort

6

Wenn Sie eine beliebige Abtastrate auf einem Gerät Wich zwingen doesen't es unterstützen, Sie Probleme haben werden.

Ich empfehle Ihnen, eine gültige Abtastrate für das laufende Gerät zu überprüfen und einzustellen (anstatt es auf 44,1 KHz zu kodieren).

Werfen Sie einen Blick auf here für einige Hinweise über , wie verfügbare Sample-Raten zu überprüfen.

+0

Ich habe versucht, dem angegebenen Link zu folgen.Ich habe den obigen Code entsprechend geschrieben (ich habe diesen Code zur Frage selbst hinzugefügt). Aber es funktioniert immer noch nicht? – NoviceMe

0

Der Code prüft nicht wirklich auf Fehler, wodurch es viel schwieriger wird herauszufinden, was auf diesen Geräten schief läuft. Bitte wie folgt vorgehen:

  1. nicht auf die Aufzeichnung bezogen (aber die Wiedergabe), aber es ist besser, wenn Sie kümmern sich um die AudioFocus nehmen .. es verloren gehen könnten und etc. All yop Notwendigkeit, hier zu wissen ist http://developer.android.com/training/managing-audio/audio-focus.html
  2. hinzufügen Anrufe AudioRecord.getState() den Zustand
  3. hinzufügen Anrufe AudioRecord.getRecordingState(), um zu überprüfen Aufzeichnungszustand
  4. In getMinBufferSize Sie gegen ERROR_BAD_VALUE
  5. überprüfen müssen, um zu überprüfen In der Lese Sie Anrufe müssen um Agai zu überprüfen nst ERROR_INVALID_OPERATION und ERROR_BAD_VALUE
  6. Sie können mit setRecordPositionUpdateListener feststellen, ob die Aufzeichnung fortgeschritten ist.

Diese Schritte + Beobachten des System logcat werden Sie in einem viel besseren Ort setzen, das Problem zu lokalisieren, oder uns mit den Informationen zur Verfügung stellen, das Problem

2

Diesen Code zu lösen, ob die Samplerate und Audio-Format überprüfen unterstützt in Ihrem Gerät. Überprüfen Sie die Kombination und sehen Sie, welche für Sie arbeitet.

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 }; 

    for (int rate : mSampleRates) { 
       for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT,AudioFormat.ENCODING_PCM_16BIT }) { 
        for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { 
         try { 
          Log.d(TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " 
            + channelConfig); 
          int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

          if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
           Log.d(TAG, "Found rate " + rate + "Hz, bits: " + audioFormat + ", channel: " 
             + channelConfig); 

         Log.d(TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " 
            + channelConfig +" supported"); 


          } 
         } catch (Exception e) { 
          Log.e(TAG, rate + "Exception, keep trying.",e); 
         } 
        } 
       } 
      } 
+1

Vielen Dank für Ihre Antwort, aber es wurde für alle Sample-Raten gefunden. Jetzt bin ich verwirrt, welches man unter diesen vier benutzt. Können Sie das bitte ausarbeiten? Danke –

+0

yeah es gefunden für alle samplerates das bedeutet es unterstützt alle sample rates, größer die sample rate besser die qualität. Sie können verwenden, was Sie wollen. Ich gebe Ihnen nur einen Weg, um herauszufinden, ob das Gerät Sample-Raten unterstützt –