2012-07-02 11 views
5

Mam napisany kod do nagrywania pliku audio przy użyciu AudioRecord i podczas zapisywania pliku na karcie SD tworzę dwie wersje.AudioRecord z regulacją wzmocnienia nie działa na urządzeniu Samsung

Wersja 1 Nagrany plik jest zapisywany na karcie SD w niezmienionej postaci.

Wersja 2 Używam funkcji wzmocnienia na nagranym pliku i zapisywania na karcie SD.

Działa to świetnie na telefonach Sony Ericson. Również głośność dźwięku w znacznym stopniu się zwiększa.

Ale staram się, aby działało na urządzeniach Samsung.

gdy gram nagrany plik brzmi to jak rozmowa Tom: P

Początkowo myślałem urządzenie Samusung nie podoba kombinacje użyłem do stworzenia AudioRecorder.

Użyłem następującego podejścia, w którym zapętlałem się do dostępnej konfiguracji i korzystałem z najlepszej konfiguracji, aby zainicjować AudioRecord.

public AudioRecord findAudioRecord() { 
    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.i("vipul", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig); 
        int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
         // check if we can instantiate and have a success 
         AudioRecord recorder = new AudioRecord(
         AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize); 

         if (recorder.getState() == AudioRecord.STATE_INITIALIZED) return recorder; 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
    return null; 
} 

Poniżej znajduje się kod, który działa dobrze na telefonach komórkowych Sony. Nie radzi sobie z pracą na urządzeniach Samsung.

public class EnvironmentRecorder extends Activity implements OnClickListener { 

    private static final int RECORDER_BPP = 16; 
    private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav"; 
    private static final String AUDIO_RECORDER_FOLDER = "MyRecorder"; 
    private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw"; 
    private static final int RECORDER_SAMPLERATE = 44100; 
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO; 
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
    private Button start, stop; 
    private AudioRecord recorder = null; 
    private int bufferSize = 0; 
    private Thread recordingThread = null; 
    private boolean isRecording = false; 
    private static int[] mSampleRates = new int[] { 
     8000, 11025, 22050, 44100 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     start = (Button) findViewById(R.id.start); 
     stop = (Button) findViewById(R.id.stop); 
     start.setOnClickListener(this); 
     stop.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) { 
     switch (view.getId()) { 
     case R.id.start: 
      startRecord(); 
      break; 
     case R.id.stop: 
      stopRecording(); 
      break; 
     } 
    } 

    public EnvironmentRecorder() { 

     try { 
      bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    private String getFilename1() { 
     String filepath = Environment.getExternalStorageDirectory().getPath(); 
     File file = new File(filepath, AUDIO_RECORDER_FOLDER); 

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

     return (file.getAbsolutePath() + "/" + "NotGained" + AUDIO_RECORDER_FILE_EXT_WAV); 
    } 

    private String getFilename2() { 
     String filepath = Environment.getExternalStorageDirectory().getPath(); 
     File file = new File(filepath, AUDIO_RECORDER_FOLDER); 

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

     return (file.getAbsolutePath() + "/" + "Gained" + AUDIO_RECORDER_FILE_EXT_WAV); 
    } 

    private String getTempFilename() { 
     String filepath = Environment.getExternalStorageDirectory().getPath(); 
     File file = new File(filepath, AUDIO_RECORDER_FOLDER); 

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

     File tempFile = new File(filepath, AUDIO_RECORDER_TEMP_FILE); 

     if (tempFile.exists()) tempFile.delete(); 

     return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE); 
    } 

    public AudioRecord findAudioRecord() { 
     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.v("vipul", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig); 
         int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

         if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
          // check if we can instantiate and have a success 
          AudioRecord recorder = new AudioRecord(
          AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize); 

          if (recorder.getState() == AudioRecord.STATE_INITIALIZED) return recorder; 
         } 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
     return null; 
    } 

    public void startRecord() { 
     /* 
     * recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
     * RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, 
     * bufferSize); 
     */ 

     recorder = findAudioRecord(); 

     recorder.startRecording(); 

     isRecording = true; 

     recordingThread = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       writeAudioDataToFile(); 
      } 
     }, "AudioRecorder Thread"); 

     recordingThread.start(); 
    } 

    private void writeAudioDataToFile() { 
     byte data[] = new byte[bufferSize]; 
     String filename = getTempFilename(); 
     FileOutputStream os = null; 

     try { 
      os = new FileOutputStream(filename); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

     int read = 0; 

     if (null != os) { 
      while (isRecording) { 
       read = recorder.read(data, 0, bufferSize); 

       if (AudioRecord.ERROR_INVALID_OPERATION != read) { 
        try { 
         os.write(data); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

      try { 
       os.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void stopRecording() { 
     if (null != recorder) { 
      isRecording = false; 

      recorder.stop(); 
      recorder.release(); 

      recorder = null; 
      recordingThread = null; 
      copyWaveFile(getTempFilename(), getFilename1(), getFilename2()); 
      deleteTempFile(); 
     } 

    } 

    private void deleteTempFile() { 
     File file = new File(getTempFilename()); 

     file.delete(); 
    } 

    private void copyWaveFile(String inFilename, String outFileName1, String outFileName2) { 
     FileInputStream in = null; 
     FileOutputStream out1 = null, out2 = null; 
     long totalAudioLen = 0; 
     long totalDataLen = totalAudioLen + 36; 
     long longSampleRate = RECORDER_SAMPLERATE; 
     int channels = 2; 
     long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; 

     byte[] data = new byte[bufferSize]; 

     try { in = new FileInputStream(inFilename); 
      out1 = new FileOutputStream(outFileName1); 
      out2 = new FileOutputStream(outFileName2); 
      totalAudioLen = in .getChannel().size(); 
      totalDataLen = totalAudioLen + 36; 

      WriteWaveFileHeader(out1, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); 
      WriteWaveFileHeader(out2, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); 

      while (in .read(data) != -1) { 

       out1.write(data); // Writing Non-Gained Data 

       float rGain = 2.5f; 
       for (int i = 0; i < data.length/2; i++) { 

        short curSample = getShort(data[i * 2], data[i * 2 + 1]); 
        if (rGain != 1) { 
         // apply gain 
         curSample *= rGain; 
         // convert back from short sample that was "gained" to 
         // byte data 
         byte[] a = getByteFromShort(curSample); 
         // modify buffer to contain the gained sample 
         data[i * 2] = a[0]; 
         data[i * 2 + 1] = a[1]; 
        } 

       } 

       out2.write(data); // Writing Gained Data 
      } 
      out1.close(); 
      out2.close(); in .close(); 

      Toast.makeText(this, "Done!!", Toast.LENGTH_LONG).show(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private short getShort(byte argB1, byte argB2) { 
     return (short)((argB1 & 0xff) | (argB2 << 8)); 

    } 

    private byte[] getByteFromShort(short x) { 
     // variant 1 - noise 
     byte[] a = new byte[2]; 
     a[0] = (byte)(x & 0xff); 
     a[1] = (byte)((x >> 8) & 0xff); 

     // variant 2 - noise and almost broke my ears - very loud 
     // ByteBuffer buffer = ByteBuffer.allocate(2); 
     // buffer.putShort(x); 
     // buffer.flip(); 

     return a; 
    } 

    private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) 
    throws IOException { 

     byte[] header = new byte[44]; 

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

     out.write(header, 0, 44); 
    } 

} 

Chciałbym wiedzieć, czy muszę dodać dodatkowe miejsce, aby moje AudioRecord było wygodne z urządzeniami Samsung.

+0

Witaj, Vipul, znalazłeś rozwiązanie? Mamy ten sam problem na Galaxy S3 i uważamy, że jest podobny do twojego. – Giuseppe

Odpowiedz

6

Walczymy również z nagrywaniem dźwięku na niektórych urządzeniach Samsung z Androidem. Niestety wygląda na to, że jest bardzo zepsuty, ponieważ nawet różne wersje tego samego modelu telefonu zachowują się inaczej w tej samej bazie kodu.

Oto moje obecne ustalenia, mając nadzieję znaleźć coś pożytecznego:

1. Przerwane Inicjalizacja:

Niestety, strategia używasz do kwerendy dla prawidłowych konfiguracji nagrywania zawiedzie przynajmniej na Samsung Modele Galaxy Young i Ace z systemem Android 2.3 Problem polega na tym, że niektóre niepoprawne konfiguracje AudioRecord zamiast po prostu nie działać, całkowicie zniszczą podsystem przechwytywania audio, jeśli spróbujemy. Aby zresetować telefon z tego stanu, musisz zresetować telefon.

2. Niezgodne Sampling-Rate wsparcie wzdłuż wersjami tego samego modelu telefonu

na starszej Galaxy Ace telefon, nagrywania @ 11025Hz, 16-bitowy mono uda. W nowszych wersjach Ace ta konfiguracja AudioRecord zostanie uznana za poprawną, ale wynikowe nagranie zostanie zniekształcone z efektem "chipmunk". Bardzo popularna aplikacja do tuningu gitarowego, która zakodowała tę częstotliwość próbkowania, nie jest w stanie dokładnie odczytać strojów na tych telefonach właśnie z powodu tego problemu!

3. Wyjątkowo niski poziom dźwięku w niektórych konfiguracjach.

W Galaxy Young and Galaxy Ace nagrywanie z mikrofonu lub domyślnego źródła dźwięku przy częstotliwości 44,100 Hz (rzekomo prędkość kanoniczna, w której wszystko powinno działać poprawnie) powoduje niezakłócone, ale ekstremalnie niskie nagrania. Nie znalazłem jeszcze sposobu na naprawienie tego innego niż wzmocnienie oprogramowania (co jest równoważne z powiększeniem obrazu o bardzo niskiej rozdzielczości, z towarzyszącymi efektami "jageddnes" wyniku).

4. Brak obsługi kanonicznej częstotliwości próbkowania 44,100 Hz dla każdego źródła sygnału audio.

W Galaxy Young and Galaxy Ace nagrywanie ze źródła kamery kończy się niepowodzeniem @ 44,100Hz. (ponownie, konfiguracja zostanie zaakceptowana jako ważna), produkując kompletne śmieci. Jednak nagrywanie z częstotliwością 8 000 Hz, 16 000 Hz i 48,000 Hz działa dobrze i umożliwia nagrywanie z akceptowalnym poziomem głośności. Frustrujące jest to, że zgodnie z dokumentacją Androida 44 100 Hz to częstotliwość próbkowania, którą powinny obsługiwać wszystkie urządzenia.

5. OpenSL nie naprawia żadnego zgłoszonego problemu.

Praca z NDK i OpenSL daje takie same opisane wyniki. Wygląda na to, że klasa AudioRecorder po prostu owija połączenia do OpenSL, a problem jest albo oparty na sprzęcie, albo pochowany na niższym poziomie w kodzie jądra.

Ta sytuacja jest bardzo niestety, ponieważ modele te stają się bardzo popularne - przynajmniej w Meksyku.

Życzymy powodzenia - i zgłoś, jeśli masz więcej szczęścia w pracy z tymi telefonami. =)

+0

Wygląda na to, że wiesz sporo o tym problemie. Mam teraz ten sam problem. Czy wiesz, czy Samsung jeszcze nie naprawił? Pytam, ponieważ nie mam urządzenia, potrzebuję 44100 Hz i nie mam pojęcia, co teraz zrobić. – stefple

+0

... przepraszam, zapomniałem powiedzieć: że użytkownicy ofc mają problem teraz, gdy moja aplikacja nie działa. Jedyne rozwiązanie, jakie teraz widzę, to to, że wykluczam te urządzenia. – stefple

+0

Hi @stefple, nie, nie wiem, czy jest jeszcze poprawka. Obecnie obsługujemy 44,100 na modelach Ace i Young, wykorzystując źródło dźwięku MIC i stosując wzmocnienie oprogramowania (pomnożenie próbek przez stałą i obcinanie wartości w przypadku przepełnienia) w celu skompensowania niskich poziomów. Jakość cierpi, ale jest wystarczająco dobre dla czterech naszych celów DSP. Nagrywanie przy użyciu CAMCORDER działa przy 48000 Hz z bardzo dobrymi poziomami głośności. Jeśli możesz sobie pozwolić na dodanie procedury konwersji częstotliwości próbkowania, możesz przejść od 48 000 Hz do 44100 Hz z niewielką utratą jakości. –

1

Regulacja wzmocnienia dźwięku Aby zwiększyć amplitudę dźwięku, należy obliczyć współczynnik wzmocnienia i pomnożyć obliczony współczynnik wzmocnienia przy każdej przechwyconej próbce. Poniższy kod to robi. P.S. Zignoruj ​​niepowiązany kod:

public class MainActivity extends Activity { 

public static final int SAMPLE_RATE = 16000; 

private AudioRecord mRecorder; 
private File mRecording; 
private short[] mBuffer; 
private final String startRecordingLabel = "Start recording"; 
private final String stopRecordingLabel = "Stop recording"; 
private boolean mIsRecording = false; 
private ProgressBar mProgressBar; 
float iGain = 1.0f; 
CheckBox gain; 

protected int bitsPerSamples = 16; 

@Override 
public void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.fragment_main); 

    initRecorder(); 

    Button bluetooth = (Button)findViewById(R.id.blue); 
    gain = (CheckBox) findViewById(R.id.checkBox1); 
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar); 

    final Button button = (Button) findViewById(R.id.start); 
    button.setText(startRecordingLabel); 

    bluetooth.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // TODO Auto-generated method stub 
      Intent i = new Intent(""); 
     } 
    }); 
    gain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 

      if (gain.isChecked()) { 
       iGain = 5.0f; 

      } else { 
       iGain = 2.0f; 
      } 
     } 
    }); 

    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(final View v) { 
      if (!mIsRecording) { 
       button.setText(stopRecordingLabel); 
       mIsRecording = true; 
       mRecorder.startRecording(); 
       mRecording = getFile("raw"); 
       startBufferedWrite(mRecording); 
      } else { 
       button.setText(startRecordingLabel); 
       mIsRecording = false; 
       mRecorder.stop(); 
       File waveFile = getFile("wav"); 
       try { 
        rawToWave(mRecording, waveFile); 
       } catch (IOException e) { 
        Toast.makeText(MainActivity.this, e.getMessage(), 
          Toast.LENGTH_SHORT).show(); 
       } 
       Toast.makeText(MainActivity.this, 
         "Recorded to " + waveFile.getName(), 
         Toast.LENGTH_SHORT).show(); 
      } 
     } 
    }); 
} 

@Override 
public void onDestroy() { 
    mRecorder.release(); 
    super.onDestroy(); 
} 

private void initRecorder() { 
    int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
      AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    mBuffer = new short[bufferSize]; 
    mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, 
      AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 
      bufferSize); 
} 

private void startBufferedWrite(final File file) { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      DataOutputStream output = null; 
      try { 
       output = new DataOutputStream(new BufferedOutputStream(
         new FileOutputStream(file))); 
       while (mIsRecording) { 
        double sum = 0; 

        int readSize = mRecorder.read(mBuffer, 0, 
          mBuffer.length); 

        final int bytesPerSample = bitsPerSamples/8; 
        final int emptySpace = 64 - bitsPerSamples; 
        int byteIndex = 0; 
        int byteIndex2 = 0; 
        int temp = 0; 
        int mLeftTemp = 0; 
        int mRightTemp = 0; 
        int a = 0; 
        int x = 0; 

        for (int frameIndex = 0; frameIndex < readSize; frameIndex++) { 

         for (int c = 0; c < 1; c++) { 

          if (iGain != 1) { 

           long accumulator = 0; 
           for (int b = 0; b < bytesPerSample; b++) { 

            accumulator += ((long) (mBuffer[byteIndex++] & 0xFF)) << (b * 8 + emptySpace); 
           } 

           double sample = ((double) accumulator/(double) Long.MAX_VALUE); 
           sample *= iGain; 
           int intValue = (int) ((double) sample * (double) Integer.MAX_VALUE); 

           for (int i = 0; i < bytesPerSample; i++) { 
            mBuffer[i + byteIndex2] = (byte) (intValue >>> ((i + 2) * 8) & 0xff); 
           } 
           byteIndex2 += bytesPerSample; 

          } 
         }// end for(channel) 

         // mBuffer[frameIndex] *=iGain; 
         if (mBuffer[frameIndex] > 32765) { 
          mBuffer[frameIndex] = 32767; 

         } else if (mBuffer[frameIndex] < -32767) { 
          mBuffer[frameIndex] = -32767; 
         } 
         output.writeShort(mBuffer[frameIndex]); 
         sum += mBuffer[frameIndex] * mBuffer[frameIndex]; 

        } 

        if (readSize > 0) { 
         final double amplitude = sum/readSize; 
         mProgressBar.setProgress((int) Math.sqrt(amplitude)); 
        } 
       } 
      } catch (IOException e) { 
       Toast.makeText(MainActivity.this, e.getMessage(), 
         Toast.LENGTH_SHORT).show(); 
      } finally { 
       mProgressBar.setProgress(0); 
       if (output != null) { 
        try { 
         output.flush(); 
        } catch (IOException e) { 
         Toast.makeText(MainActivity.this, e.getMessage(), 
           Toast.LENGTH_SHORT).show(); 
        } finally { 
         try { 
          output.close(); 
         } catch (IOException e) { 
          Toast.makeText(MainActivity.this, e.getMessage(), 
            Toast.LENGTH_SHORT).show(); 
         } 
        } 
       } 
      } 
     } 
    }).start(); 
} 

private void rawToWave(final File rawFile, final File waveFile) 
     throws IOException { 

    byte[] rawData = new byte[(int) rawFile.length()]; 
    DataInputStream input = null; 
    try { 

     input = new DataInputStream(new FileInputStream(rawFile)); 
     input.read(rawData); 
    } finally { 
     if (input != null) { 
      input.close(); 
     } 
    } 

    DataOutputStream output = null; 
    try { 
     output = new DataOutputStream(new FileOutputStream(waveFile)); 
     // WAVE header 
     // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ 
     writeString(output, "RIFF"); // chunk id 
     writeInt(output, 36 + rawData.length); // chunk size 
     writeString(output, "WAVE"); // format 
     writeString(output, "fmt "); // subchunk 1 id 
     writeInt(output, 16); // subchunk 1 size 
     writeShort(output, (short) 1); // audio format (1 = PCM) 
     writeShort(output, (short) 1); // number of channels 
     writeInt(output, SAMPLE_RATE); // sample rate 
     writeInt(output, SAMPLE_RATE * 2); // byte rate 
     writeShort(output, (short) 2); // block align 
     writeShort(output, (short) 16); // bits per sample 
     writeString(output, "data"); // subchunk 2 id 
     writeInt(output, rawData.length); // subchunk 2 size 
     // Audio data (conversion big endian -> little endian) 
     short[] shorts = new short[rawData.length/2]; 
     ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN) 
       .asShortBuffer().get(shorts); 
     ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2); 

     for (short s : shorts) { 

      // Apply Gain 
      /* 
      * s *= iGain; if(s>32767) { s=32767; } else if(s<-32768) { 
      * s=-32768; } 
      */ 
      bytes.putShort(s); 
     } 
     output.write(bytes.array()); 
    } finally { 
     if (output != null) { 
      output.close(); 
     } 
    } 
} 

private File getFile(final String suffix) { 
    Time time = new Time(); 
    time.setToNow(); 
    return new File(Environment.getExternalStorageDirectory(), 
      time.format("%Y%m%d%H%M%S") + "." + suffix); 
} 





private void writeInt(final DataOutputStream output, final int value) 
     throws IOException { 
    output.write(value >> 0); 
    output.write(value >> 8); 
    output.write(value >> 16); 
    output.write(value >> 24); 
} 

private void writeShort(final DataOutputStream output, final short value) 
     throws IOException { 
    output.write(value >> 0); 
    output.write(value >> 8); 
} 

private void writeString(final DataOutputStream output, final String value) 
     throws IOException { 
    for (int i = 0; i < value.length(); i++) { 
     output.write(value.charAt(i)); 
    } 
} 
} 
Powiązane problemy