2

我正在开发一个测试应用程序以在 Android 上集成 soundtouch(一个开源音频处理库)。

我的测试应用程序已经可以接收来自麦克风的输入,通过 soundtouch 传递音频并将处理后的音频输出到 AudioTrack 实例。

我的问题是,如何将 AudioTrack 的输出更改为设备上的新文件?

这是我的应用程序中的相关代码(我正在将 soundtouch 的输出处理到 AudioTrack 的输入中)

// the following code is a stripped down version of my code
// in no way its supposed to compile or work.  Its here for reference purposes
// pre-conditions 
// parameters -  input : byte[]
soundTouchJNIInstance.putButes(input);
int bytesReceived = soundTouchJNIInstance.getBytes(input);
audioTrackInstance.write(input, 0, bytesReceived);

关于如何解决这个问题的任何想法?谢谢!

4

6 回答 6

0

我使用一个简单的测试代码片段来编写我的音频字节数组:

public void saveAudio(byte[] array, string pathAndName)
{
  FileOutputStream stream = new FileOutputStream(pathAndName);
  try {
      stream.write(array);
  } finally {
      stream.close();
  }
}

如果您要在生产环境中使用它,您可能需要添加一些异常处理,但是每当我处于开发阶段或个人非发布项目时,我都会利用上述方法来保存音频。

附录

经过一些简短的思考后,我将我的代码段更改为以下稍微更健壮的格式:

public void saveAudio(byte[] array, string pathAndName)
{
  try (FileOutputStream stream= new FileOutputStream(pathAndName)) {
      stream.write(array);
  } catch (IOException ioe) {
      ioe.printStackTrace();
  } finally {
      stream.close();
  }
}
于 2014-04-09T09:15:05.593 回答
0

我根本不知道有声音的触摸,我提供的链接也没有处理 jni 代码,但如果它对你有任何帮助,你可以看看它:http: //i-liger.com/article/android -wav 录音

于 2014-04-05T11:29:43.023 回答
0

编写 byteArray 的最佳方法是:

public void writeToFile(byte[] array) 
{ 
    try 
    { 
        String path = "Your path.mp3"; 
        File file = new File(path);
        if (!file.exists()) {
        file.createNewFile();
        }

        FileOutputStream stream = new FileOutputStream(path); 
        stream.write(array); 
    } catch (FileNotFoundException e1) 
    { 
        e1.printStackTrace(); 
    } 
} 
于 2014-04-04T07:49:12.130 回答
0

您可以使用使用 SequenceInputStream 的方法,在我的应用程序中,我只是将 MP3 文件合并为一个并使用 JNI 库 MPG123 播放它,但我使用 MediaPlayer 测试文件没有问题。

这段代码不是最好的,但它可以工作......

private void mergeSongs(File mergedFile,File...mp3Files){
        FileInputStream fisToFinal = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(mergedFile);
            fisToFinal = new FileInputStream(mergedFile);
            for(File mp3File:mp3Files){
                if(!mp3File.exists())
                    continue;
                FileInputStream fisSong = new FileInputStream(mp3File);
                SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
                byte[] buf = new byte[1024];
                try {
                    for (int readNum; (readNum = fisSong.read(buf)) != -1;)
                        fos.write(buf, 0, readNum);
                } finally {
                    if(fisSong!=null){
                        fisSong.close();
                    }
                    if(sis!=null){
                        sis.close();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(fos!=null){
                    fos.flush();
                    fos.close();
                }
                if(fisToFinal!=null){
                    fisToFinal.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
于 2014-04-09T17:23:03.010 回答
0

希望您已经从麦克风获取输入声音并保存在文件中。

首先,将 JNI 库导入您的 oncreate 方法:

System.loadLibrary("soundtouch");
System.loadLibrary("soundstretch");

Soundstrech 库:

public class AndroidJNI extends SoundStretch{
    public final static SoundStretch soundStretch = new SoundStretch();
}

现在您需要使用输入文件路径和所需的输出文件调用 soundstrech.process 以将处理后的语音存储为参数:

AndroidJNI.soundStretch.process(dataPath + "inputFile.wav", dataPath + "outputFile.wav", tempo, pitch, rate);
        File sound = new File(dataPath + "outputFile.wav");
        File sound2 = new File(dataPath + "inputFile.wav");       
        Uri soundUri = Uri.fromFile(sound);

soundUri 可以作为媒体播放器的播放源提供:

MediaPlayer mediaPlayer = MediaPlayer.create(this, soundUri);
        mediaPlayer.start();

另请注意,应通过声明 Array of Sample Rates 动态选择记录的样本大小:

int[] sampleRates = { 44100, 22050, 11025, 8000 }
于 2014-04-04T03:49:02.427 回答
0

我认为实现这一点的最佳方法是将音频转换为byte[]数组。假设您已经这样做了(如果没有,请对其进行评论,我将提供一个示例),上面的代码应该可以工作。这假设您将它保存在一个sdcard名为新目录的外部目录中AudioRecording,并将其另存为audiofile.mp3.

final File soundFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "AudioRecording/");
soundFile.mkdirs();
final File outFile = new File(soundFile, 'audiofile.mp3');

try {
  final FileOutputStream output = new FileOutputStream(outFile);
  output.write(yourByteArrayWithYourAudioFileConverted);
  output.close();
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

mkdirs()如果缺少父目录,该方法将尝试构建所有父目录。因此,如果您打算存储在 2 级或更多级深度目录中,这将创建所有结构。

于 2014-04-02T19:07:01.510 回答