java 代码转换音频数据格式(字节数组转换)

目前音频格式有很多,本文针对PCM 音频文件进行转换

所谓pcm 就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。PCM轨迹与视频轨迹不同,故也可用于后期录音。但在Hi8的摄像机中要实现PCM,必须通过其他的专业器材,仅靠摄像机是无法达到该效果的。

 

alaw 与 ulaw 都为pcm 文件编码格式

参考:

https://www.2cto.com/kf/201504/390076.html

 

8k8bit pcm 文件指的是采样点为8000,采用精度为8bit, bit可以理解为每个采样点大小

这种音频格式的录音为 8000*8*1(声道数)/8/1024 = 8kbs

 

同理8k16bit pcm,16k16bit pcm文件

 

下面介绍下 这些音频格式利用java代码相互转换的过程

由于网上有很多工具能够直接将完整的音频文件直接转换为相应的格式,这里就不多介绍了,

下面介绍的是如果音频文件并非完整的,而是一段二进制的数组

比如说实时的语音流转换

 

1 声道数的转换

 

8K8bit立体音 分离 成单声道(立体语音是8kAlaw)

立体音本身的采样就是左声道采样一个点,右声道采样一个记录在一起,知道这个原理,分离就很简单了。

 

/**
 * 立体音 分离 成单声道(立体语音是8kAlaw)
 * 
 * @param stereoBytes
 * @return
 * @throws IOException
 */
public static byte[][] stereo2M
下面是一个简单的 Java 代码示例,可以使用降噪算法来处理音频文件。这个示例使用了一个名为“SpectralSubtraction”的算法,它将信号的频谱进行分析,并且从中剔除噪声。这个算法需要一些音频处理的基础知识,但是代码本身并不复杂。 首先,你需要导入 Java音频处理库: ``` import javax.sound.sampled.*; ``` 然后,你可以使用以下代码来读取你想要处理的音频文件: ``` AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("input.wav")); ``` 其中,"input.wav" 是你要读取的音频文件的路径。 接下来,你需要定义一些常量。这些常量将会影响你的降噪算法的效果。例如,你可以根据需要修改采样率、窗口大小和噪声门限等参数。 ``` final int sampleRate = 16000; final int windowSize = 512; final int hopSize = 256; final double noiseThreshold = 0.15; ``` 然后,你可以使用以下代码来进行降噪处理: ``` // 读取音频数据 byte[] audioBytes = new byte[(int) (audioInputStream.getFrameLength() * audioInputStream.getFormat().getFrameSize())]; audioInputStream.read(audioBytes); // 将字节数组转换为采样数组 double[] audioSamples = new double[audioBytes.length / 2]; for (int i = 0; i < audioSamples.length; i++) { audioSamples[i] = ((short) ((audioBytes[i * 2] & 0xff) | (audioBytes[i * 2 + 1] << 8))) / 32768.0; } // 计算频谱 FFT fft = new FFT(windowSize); int numFrames = (audioSamples.length - windowSize) / hopSize + 1; double[][] frames = new double[numFrames][windowSize]; for (int i = 0; i < numFrames; i++) { for (int j = 0; j < windowSize; j++) { frames[i][j] = audioSamples[i * hopSize + j]; } fft.forward(frames[i]); } // 计算噪声门限 double[] spectrum = new double[windowSize / 2 + 1]; double[] noiseThresholds = new double[spectrum.length]; for (int i = 0; i < spectrum.length; i++) { double sum = 0.0; for (int j = 0; j < numFrames; j++) { double magnitude = Math.sqrt(frames[j][2 * i] * frames[j][2 * i] + frames[j][2 * i + 1] * frames[j][2 * i + 1]); spectrum[i] += magnitude / numFrames; if (magnitude > noiseThreshold) { sum += 1.0; } } noiseThresholds[i] = (sum / numFrames) * noiseThreshold; } // 进行降噪 for (int i = 0; i < numFrames; i++) { for (int j = 0; j < windowSize / 2 + 1; j++) { double magnitude = Math.sqrt(frames[i][2 * j] * frames[i][2 * j] + frames[i][2 * j + 1] * frames[i][2 * j + 1]); if (magnitude < noiseThresholds[j]) { frames[i][2 * j] = 0.0; frames[i][2 * j + 1] = 0.0; } } fft.inverse(frames[i]); } // 合并所有帧 double[] denoisedSamples = new double[(numFrames - 1) * hopSize + windowSize]; for (int i = 0; i < numFrames; i++) { for (int j = 0; j < windowSize; j++) { if (i == 0) { denoisedSamples[j] = frames[i][j]; } else { denoisedSamples[i * hopSize + j] += frames[i][j]; } } } // 将采样数组转换字节数组 byte[] denoisedBytes = new byte[audioBytes.length]; for (int i = 0; i < denoisedSamples.length; i++) { short sample = (short) (denoisedSamples[i] * 32768.0); denoisedBytes[i * 2] = (byte) (sample & 0xff); denoisedBytes[i * 2 + 1] = (byte) (sample >> 8); } // 将降噪后的音频数据写入文件 AudioFormat audioFormat = new AudioFormat(sampleRate, 16, 1, true, false); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(denoisedBytes); AudioInputStream denoisedAudioInputStream = new AudioInputStream(byteArrayInputStream, audioFormat, denoisedBytes.length / audioFormat.getFrameSize()); AudioSystem.write(denoisedAudioInputStream, AudioFileFormat.Type.WAVE, new File("output.wav")); ``` 其中,"output.wav" 是处理后的音频文件的路径。 这个示例中的降噪算法只是其中一种,你可以根据需要使用其他算法。请注意,音频处理是一个非常复杂的领域,需要深入的知识和经验才能取得好的效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值