引入 maven 依赖:
<dependency>
<groupId>net.sourceforge.jtransforms</groupId>
<artifactId>jtransforms</artifactId>
<version>2.4.0</version>
</dependency>
原理:
- 将音频信号进行分帧处理,将每一帧的数据进行傅里叶变换,得到短时傅里叶变换(STFT)。
- 对于每一帧的频谱,可以通过观察频谱图的特征来确定人声和旋律所在的频率范围。
- 根据人声和旋律所在的频率范围,可以将频谱图中对应的频率区域置零,以实现人声的去除。
- 对处理后的频谱进行逆傅里叶变换,得到去除人声的音频信号。
- 可以进一步对去除人声的音频信号进行处理,如滤波、增强等,以提取出旋律。
java 代码实现:todo文章来源:https://www.toymoban.com/news/detail-819477.html
可能用到的工具类 AudioUtils.java:文章来源地址https://www.toymoban.com/news/detail-819477.html
import javax.sound.sampled.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
public class AudioUtils {
public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
File file = new File("C:\\E\\素材\\音频\\wav\\一生所爱.wav");
double[] doubleArray = wavToDoubleArray(file);
System.out.println( doubleArray.length );
int partLength = doubleArray.length / 10;
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, 0, partLength),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part1.wav" ) );
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, partLength, partLength * 2),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part2.wav" ) );
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, partLength * 2, partLength * 3),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part3.wav" ) );
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, partLength * 3, partLength * 4),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part4.wav" ) );
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, partLength * 4, partLength * 5),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part5.wav" ) );
doubleArrayToWAV( Arrays.copyOfRange(doubleArray, partLength * 5, partLength * 6),new File( "C:\\E\\素材\\音频\\wav\\一生所爱_part6.wav" ) );
}
public static double[] wavToDoubleArray(File mp3File) throws UnsupportedAudioFileException, IOException {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(mp3File);
AudioFormat audioFormat = audioInputStream.getFormat();
int numChannels = audioFormat.getChannels();
int sampleSizeInBytes = audioFormat.getSampleSizeInBits() / 8;
int frameSize = numChannels * sampleSizeInBytes;
int bufferSize = (int) (audioInputStream.getFrameLength() * frameSize);
byte[] audioBytes = new byte[bufferSize];
audioInputStream.read(audioBytes);
double[] audioData = new double[audioBytes.length / 2];
for (int i = 0, j = 0; i < audioBytes.length; i += 2, j++) {
int sample = (audioBytes[i + 1] << 8) | (audioBytes[i] & 0xFF);
audioData[j] = sample / 32768.0;
}
return audioData;
}
public static void doubleArrayToWAV(double[] audioData, File outputFile) throws IOException, UnsupportedAudioFileException {
AudioFormat audioFormat = new AudioFormat(44100, 16, 2, true, false);
byte[] audioBytes = new byte[audioData.length * 2];
for (int i = 0, j = 0; i < audioData.length; i++, j += 2) {
short sample = (short) (audioData[i] * 32767);
audioBytes[j] = (byte) (sample & 0xFF);
audioBytes[j + 1] = (byte) ((sample >> 8) & 0xFF);
}
AudioInputStream audioInputStream = new AudioInputStream(new ByteArrayInputStream(audioBytes), audioFormat, audioData.length);
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, outputFile);
}
}
到了这里,关于java 使用 jtransforms 傅里叶变换库实现删除 wav 歌曲中的人声、提取歌曲旋律功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!