2014-12-29 4 views
2

Давайте предположим, что у меня есть звуковой файл WAV с предложением:Если извлеченный аудио-образец должен содержаться внутри исходного источника при сравнении байтов?

+-----------+----------------------------------------+ 
| meta data | 'Audio recognition sometimes is trick' |.wav 
+-----------+----------------------------------------+ 

Теперь рассмотрим открытие этого звука в Audacity и извлечение и сохранение слово «иногда» в другом файле на основе его волнового дро.

+-----------+-------------+ 
| meta data | 'sometimes' |.wav 
+-----------+-------------+ 

Затем я использовал этот Java код, чтобы получить звуковые данные только из двух файлов:

//... 
    Path source = Paths.get("source.wav"); 
    Path sample = Paths.get("sometimes.wav"); 
    int index = compare(transform(source), transform(sample)); 
    System.out.println("Shouldn't I be greater than -1!? " + (index > -1)); 
    //... 

    private int compare(int[] source, int[] sample) throws IOException { 
     return Collections.indexOfSubList(Arrays.asList(source), Arrays.asList(sample)); 
    } 

    private int[] transform(Path audio) throws IOException, UnsupportedAudioFileException { 
    try (AudioInputStream ais = AudioSystem.getAudioInputStream(
      new ByteArrayInputStream(Files.readAllBytes(audio)))) { 

     AudioFormat format = ais.getFormat(); 
     byte[] audioBytes = new byte[(int) (ais.getFrameLength() * format.getFrameSize())]; 
     int nlengthInSamples = audioBytes.length/2; 
     int[] audioData = new int[nlengthInSamples]; 
     for (int i = 0; i < nlengthInSamples; i++) { 
      int LSB = audioBytes[2*i]; /* First byte is LSB (low order) */ 
      int MSB = audioBytes[2*i+1]; /* Second byte is MSB (high order) */ 
      audioData[i] = (MSB << 8) | (255 & LSB); 
     } 
     return audioData; 
    } 
} 

Сейчас идет мой вопрос снова.

Не должен ли этот код находить байты аудиоданных иногда в исходном звуковом файле с учетом упомянутого ранее извлечения?

Я пытался сравнивать содержимое в виде строки, но не повезло вообще:

new String(source).contains(new String(sample)); 

Может кто-то момент, что я здесь отсутствует?

+0

Являются ли эти несжатые (PCM) WAV? Кроме того, каков размер фрейма в двух файлах? – NPE

+2

Я смущен методом чтения аудиофайлов. Почему бы не использовать «AudioInputStream ais = AudioSystem.getAudioInputStream (url)»; Предполагается, что вы передаете URL-адрес файла вместо Path, который должен работать независимо от того, находится ли ресурс в банке или вне программы. Затем проверьте сравнение массивов byte [] перед тестированием после декодирования в PCM. Это мое предложение, что я сделал бы в качестве первого шага к решению вопроса. Если исходный файл и клип Audacity не совпадают с форматом, получившийся PCM, несомненно, будет отличаться, даже если звучит одинаково. –

+0

@Phil. На самом деле ваше первое предложение упрощает некоторые строки, спасибо. Но даже сравнивая байты без преобразования, я не могу найти образец внутри исходного аудиофайла. Учитывая, что я извлек образец из источника с помощью Audacity, предполагается, что будет сохранено количество каналов, скорость и т. Д., Правильно? Тем не менее, вот то, что AudioFormat, полученный от AudioInputStream, показывает: PCM_SIGNED 22050.0 Гц, 16 бит, моно, 2 байта/фрейм, little-endian PCM_SIGNED 22050.0 Гц, 16 бит, моно, 2 байта/кадр, малоконечный – zeh

ответ

0

@Phil, вы - парень! Ваши советы привели меня к решению!

  1. Звуковое извлечение образца Audacity кодировало выборки байтов несколькими способами;

  2. Я написал программу Java, чтобы идентифицировать тишину в исходном аудио, а затем я разделил несколько слов сэмплов;

  3. Сравнивая исходные и новые образцы несанкционированного доступа!

Вот новое преобразование и сравнить:

private int compare(byte[] captchaData, byte[] sampleData) throws IOException { 
    return new String(captchaData).indexOf(new String(sampleData)); 
} 

private byte[] transform(Path audio) throws IOException, UnsupportedAudioFileException { 
    AudioInputStream ais = AudioSystem.getAudioInputStream(audio.toFile()); 
    AudioFormat format = ais.getFormat(); 
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { 
     int nBufferSize = 1024 * format.getFrameSize(); 
     byte[] abBuffer = new byte[nBufferSize]; 
     int nBytesRead; 
     while ((nBytesRead = ais.read(abBuffer)) > -1) { 
      baos.write(abBuffer, 0, nBytesRead); 
     } 
     return baos.toByteArray(); 
    } 
} 

разветвителя:

private List<byte[]> split(byte[] audioData) { 
    System.out.println(audioData.length); 
    List<byte[]> byteList = new ArrayList<>(); 
    int zeroCounter = 0; 
    int lastPos = 0; 
    for (int i = 0; i < audioData.length; i++) { 
     if (audioData[i] >= -1 && audioData[i] <= 1) { 
      zeroCounter++; //too many leading 'zeros' could indicate silence or very low noise... 
     } else if (zeroCounter > 0) { 
      if (zeroCounter > 2000) { 
       int from = lastPos; 
       int to = i - (zeroCounter/2); 
       byteList.add(
        Arrays.copyOfRange(
         audioData, 
         from, 
         to)); 
       System.out.println("split from: " + from + " to: " + to); 
       lastPos = to; 
      } 
      zeroCounter = 0; 
     } 
    } 
    return byteList; 
} 

Спасибо!