2017-02-10 4 views
1

Я делаю простое приложение для Android, где я записываю что-то с микрофона смартфона, сохраняю его в файле, а затем воспроизвожу этот файл.Android: - конвертировать записанный аудиофайл в массив с плавающей точкой

Теперь я хочу применить фильтр высоких частот к этому аудиофайлу, но для этого мне нужно сначала преобразовать аудиофайл в массив с плавающей точкой. Может кто-то, пожалуйста, помогите мне с этим.

Благодаря

package abc.com.please; 

import android.content.pm.PackageManager; 
import android.media.MediaPlayer; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.os.Environment; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 


public class MainActivity extends AppCompatActivity { 

private static MediaRecorder mediaRecorder = new MediaRecorder(); 
private static MediaPlayer mediaPlayer; 

private static String audioFilePath; 
private static Button stopButton; 
private static Button playButton; 
private static Button recordButton; 

private boolean isRecording = false; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    recordButton = (Button) findViewById(R.id.recordButton); 
    playButton = (Button) findViewById(R.id.playButton); 
    stopButton = (Button) findViewById(R.id.stopButton); 

    if (!hasMicrophone()) 
    { 
     stopButton.setEnabled(false); 
     playButton.setEnabled(false); 
     recordButton.setEnabled(false); 
    } else { 
     playButton.setEnabled(false); 
     stopButton.setEnabled(false); 
    } 

    audioFilePath = 
      Environment.getExternalStorageDirectory().getAbsolutePath() 
        + "/myaudio.3gp"; 


    recordButton.setOnClickListener(new View.OnClickListener(){ 

     public void onClick (View v) 
     { 

      isRecording = true; 
      stopButton.setEnabled(true); 
      playButton.setEnabled(false); 
      recordButton.setEnabled(false); 

      try { 
       mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
       mediaRecorder.setOutputFile(audioFilePath); 
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
       mediaRecorder.prepare(); 
       mediaRecorder.start(); 
      }catch (Exception e) { 
       e.printStackTrace(); 

      } 



     } 
    }); 

    stopButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick (View view) 
     { 

      stopButton.setEnabled(false); 
      playButton.setEnabled(true); 
      if (isRecording) 
      { 
       recordButton.setEnabled(false); 
       isRecording = false; 
       mediaRecorder.stop(); 
       mediaRecorder.release(); 
       recordButton.setEnabled(true); 
      } 
      else 
      { 
       Toast.makeText(getApplicationContext(),"No recording going  on",Toast.LENGTH_SHORT).show(); 
      } 
     }}); 

    playButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) 

     { 

      playButton.setEnabled(false); 
      recordButton.setEnabled(false); 
      stopButton.setEnabled(true); 
      try { 
       mediaPlayer = new MediaPlayer(); 
       mediaPlayer.setDataSource(audioFilePath); 
       mediaPlayer.prepare(); 
       mediaPlayer.start(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    }); 
} 

protected boolean hasMicrophone() { 
    PackageManager pmanager = this.getPackageManager(); 
    return pmanager.hasSystemFeature(
      PackageManager.FEATURE_MICROPHONE); 
} 








} 
+0

Проверить это [Stack Переполнение вопрос] [1] [1]: http://stackoverflow.com/questions/6235016/convert-wav-audio-format-byte-array-to- плавающая точка –

ответ

1

Детали преобразования байт-на-поплавка будет зависеть от формата файла, который вы используете для вашего звукового файла. Я не могу сказать, что этот формат из вашего кода. Если ваш файл WAV, 44100 кадров в секунду, 16 бит, мало-endian, стерео (это стандартный формат Java, формат «CD»), вы можете попробовать использовать следующий код, который я написал. Ключевой момент преобразования, когда два байта объединяется и преобразуется в одной цифре (где «буфер» содержит данные считываются в из звукового файла:

float audioVal = (buffer[bufferIdx++] & 0xff) 
         | (buffer[bufferIdx++] << 8); 

Если это большой обратный порядок байт, обратного порядок смены Если вы используете 24 или 32 бит, то вы бы выбрали ИЛИ в сдвигах < < 16 и < < 24, соответственно. С 16-разрядным результатом будет использоваться диапазон коротких, поэтому для нормализации ситуации необходимо деление на 32767. result to [-1..1].

Я использую следующее в контексте Java некоторое время без проблем, но я не знаю, поддерживает ли Android javax.sound.sampled.Aud ioInputStream и т. д. Может быть, еще полезно увидеть преобразование в контексте прочитанного файла? Код предполагает, что у нас есть аудиоформат «Качество компакт-диска» и что аудиофайл не длиннее целого числа Integer.MAX.

public float[] loadSoundFileURL(URL url) throws UnsupportedAudioFileException, 
     IOException 
{ 
    AudioInputStream ais = AudioSystem.getAudioInputStream(url); 

    int framesCount = (int)ais.getFrameLength(); 

    // assuming stereo format, so two entries per frame 
    float[] temp = new float[framesCount * 2]; 
    long tempCountdown = temp.length; 

    int bytesRead = 0; 
    int bufferIdx; 
    int clipIdx = 0; 
    byte[] buffer = new byte[1024]; 
    while((bytesRead = ais.read(buffer, 0, 1024)) != -1) 
    { 
     bufferIdx = 0; 
     for (int i = 0, n = (bytesRead >> 1); i < n; i ++) 
     { 
      if (tempCountdown-- >= 0) 
      { 
       temp[clipIdx++] = 
         (buffer[bufferIdx++] & 0xff) 
         | (buffer[bufferIdx++] << 8) ; 
      } 
     } 
    } 

    // QUESTION: better to do following in above loop? 
    for (int i = 0; i < temp.length; i++) 
    { 
     temp[i] = temp[i]/32767f; 
    } 

    return temp; 
}