问题
First of all, I got a project to change the frequency of a WAVE file and I need to do so in Java.
I have used AudioSystem in java to get the bytes of the audio data (excluding the file header). Now I get an array of bytes of the data, I want to change it from the time domain into the frequency domain and after manipulating the frequency, I want to change it back into the time domain. Here's the code:
public byte[] getWAVByte(){
ByteArrayOutputStream out = new ByteArrayOutputStream();
try{
File f = new File("audio.wav");
AudioInputStream in = AudioSystem.getAudioInputStream(f);
int read;
byte[] buff = new byte[(int)f.length()];
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();
return audioBytes;
}catch(Exception e){
e.printStackTrace();
}
}
Now that I have an array of bytes in audioBytes, I want to change it into another array of bytes in frequency domain. I have read that you can do it with Fourier Transform, but my teacher said that it's really complex and it's not within my project's scope. So is there any other way to do this? Or is there any java library that can help me get the array of bytes in frequency domain?
回答1:
Stephan M. Bernsee wrote how do it in Frequency Domain, and you can find your source code to download in C, one guy did a port to java to your luck!
http://svn.assembla.com/svn/mm1ws08/Abgabe2/src/Effects/PitchShift.java
Yeah if you multiple or divide one value by your array of bytes you are just increase or decrease the amplitude signal, to change the Frequency in Time Domain, do you need find the glottal position click, apply one centred window over every glottal position, and now move each window to a new time position, in this step you can add or exclude some window, this change the frequency of the signal, and at the end make a Overlap Add over all windowed glottis, this method is called PSOLA
回答2:
Thanks ederwander for the pointers on Pitch Shifting.
TarsosDSP ported the code from Stephan M. Bernsee to Java here, they also provide an example using another method here.
I ended up using Superpowered AdvancedAudioPlayer class as I already had it in for other purposes. You basically use the PlayerExample project and add two lines at the beginning of the audioProcessing callback:
player->setTempo(1.0, true); // Needed for the pitch shifting to work
player->setPitchShift(-12); // Pitch shift one octave down
来源:https://stackoverflow.com/questions/20218634/change-an-array-of-byte-of-audio-sample-to-frequency