Я работал над проектом по выявлению повторяющихся сегментов в песнях.Я использую класс Java AudioInputStream
для хранения файла .wav
в экземпляре AudioInputStream.Затем я использую функцию .read()
для сохранения звука в байтовом массиве.
Мой подход к поиску повторяющегося сегмента - взять небольшой клип и проверить остаток байтового массива на идентичную последовательность байтов.Поэтому я беру 1-секундный клип от начала файла и аппроксимирую конечный индекс в байтовом массиве.Наконец, я перебираю оставшуюся часть байтового массива в поисках идентичной последовательности байтов, как 1-секундный клипКажется, мой код идентифицирует повторяющиеся клипы, но когда я конвертирую индекс, в котором найден повторяющийся сегмент, во временную метку, звук не совпадает.
Извините, если этот вопрос слишком расплывчатый.Буду очень признателен за вашу помощь.
class Skiphold{
public static void main(String args[])
{
AudioInputStream bytes = audio2byteArray("/Users/edwardcox/Desktop/mp3/Merged_flux.wav"); //conver this audio file to a stream
try {
int maxBytes = bytes.available();
byte[] soundData = new byte[maxBytes];
bytes.read(soundData); //copy bytes into an array for reading data
float frames = 1000 * bytes.getFrameLength();
float fps = bytes.getFormat().getFrameRate();
float durationMs = frames / fps; //get the length of the clip
int endIndex = byteSizedClip(soundData,bytes,durationMs); //finds index of the 1 second mark in the clip. Range from i=0 to i=endIndex will be used to find repeats
System.out.println("end index is " + endIndex);
for (int i=endIndex+1;i<soundData.length - endIndex;i++) //iterate through the byte array
{
int sampleCount = 0;
//check for a match, starting after endIndex
for (int j=i;j<i+endIndex;j++)
{
//break if no match
if (soundData[j]!=soundData[sampleCount]) {
break;
}
if (j==i+endIndex-1) {
float prop = (float)j/(float)soundData.length;
float sec = prop * durationMs / 1000;
System.out.println("found a match at index " + j + " at " + sec + " seconds"); //not lined up correctly. Delayed a second or two
}
sampleCount++;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*select a short clip that will be repeated in the song */
static int byteSizedClip(byte[] wholeClip,AudioInputStream bytes,float durationMs) {
int sampleSize = 1000; //number of milliseconds for repeated segment
float prop = sampleSize / durationMs;
int endIndex = (int) (wholeClip.length * prop); //upper bound of end of clip
return endIndex;
}
static AudioInputStream audio2byteArray(String filename)
{
File file = new File(filename);
AudioInputStream in;
try {
in = AudioSystem.getAudioInputStream(file);
AudioInputStream din = null;
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
return din;
} catch (UnsupportedAudioFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}