Android 将音频字节数组保存到音频文件中
我正在开发一个测试应用程序,将soundtouch集成到Android上的开源音频处理库中 我的测试应用程序已经可以接收来自麦克风的输入,通过soundtouch传递音频,并将处理后的音频输出到AudioTrack实例 我的问题是,如何将AudioTrack的输出更改为设备上的新文件 下面是我的应用程序中的相关代码,我正在将soundtouch的输出处理为AudioTrack的输入Android 将音频字节数组保存到音频文件中,android,audio,file-io,soundtouch,Android,Audio,File Io,Soundtouch,我正在开发一个测试应用程序,将soundtouch集成到Android上的开源音频处理库中 我的测试应用程序已经可以接收来自麦克风的输入,通过soundtouch传递音频,并将处理后的音频输出到AudioTrack实例 我的问题是,如何将AudioTrack的输出更改为设备上的新文件 下面是我的应用程序中的相关代码,我正在将soundtouch的输出处理为AudioTrack的输入 // the following code is a stripped down version of my co
// 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);
关于如何解决这个问题有什么想法吗?谢谢 我认为实现这一点的最佳方法是将音频转换为字节[]数组。假设您已经这样做了,如果没有,请对其进行注释,我将提供一个示例,上面的代码应该可以工作。这假设您正在将其保存在名为AudioRecording的新目录中的外部SD卡中,并将其另存为audiofile.mp3
如果缺少父目录,mkdirs方法将尝试构造所有父目录。因此,如果您计划存储在2级或更高级别的深度目录中,这将创建所有结构。希望您已经从麦克风获得输入语音并保存在文件中 首先,将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();
还请注意,应通过声明采样率数组动态选择记录的样本大小:
int[] sampleRates = { 44100, 22050, 11025, 8000 }
写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();
}
}
我根本不知道声音触摸,我提供的链接没有涉及jni代码的地方,但如果它对您有任何帮助,您可以查看一下:我使用一个简单的测试代码片段来编写音频字节数组:
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();
}
}
您可以使用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();
}
}
}
我上不了伸展课。。我该怎么办??我正在获取SoundStretch无法解析为类型,因为导入不起作用导入org.tecunhuman.jni.SoundStretch;
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();
}
}
}