Java - настройка скорости воспроизведения файла WAV - PullRequest
0 голосов
/ 30 сентября 2018

Я, скорее всего, плотный, но я не могу найти решение моей проблемы

( ПРИМЕЧАНИЕ: Я МОГУ найти много людей, сообщающих об этой проблеме, похоже, этопроизошло в результате более новой Java (возможно 1.5?). Возможно, SAMPLE_RATE больше не поддерживается? Я не могу найти никакого решения) .

Я пытаюсь настроить SAMPLE_RATE для ускорения / замедления песни.Я могу успешно воспроизвести файл .wav без проблем, поэтому я посмотрел на FloatControl, который работал для регулировки громкости:

public void adjustVolume(String audioType, float gain) {
        FloatControl gainControl = null;

        gainControl = (FloatControl) clipSFX.getControl(FloatControl.Type.MASTER_GAIN);
                if(gain > MAX_VOLUME)
                    gain = MAX_VOLUME;
                if(gain < MIN_VOLUME)
                    gain = MIN_VOLUME;

            //set volume
            gainControl.setValue(gain);
    }

Но при попытке перевести этот принцип в SAMPLE_RATE я очень рано получаю сообщение об ошибкеstage:

    public void adjustVolume(String audioType, float gain) {
        FloatControl gainControl = null;

        gainControl = (FloatControl) clipSFX.getControl(FloatControl.Type.SAMPLE_RATE);
        //ERROR: Exception in thread "Thread-3" java.lang.IllegalArgumentException: Unsupported control type: Sample Rate

        //I haven't gotten this far yet since the above breaks, but in theory will then set value?
            gainControl.setValue(gain);
}

Все, что я нашел в Интернете, похоже, связано с получением информации с микрофона или какой-либо внешней линии и, похоже, не переводится на использование аудиофайла, поэтому я не уверен, чтоЯ скучаю.Любая помощь будет оценена!Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Также возможно изменять скорость с помощью линейной интерполяции при прохождении аудиоданных.

Звуковые значения располагаются в массиве, и курсор обычно переходит от значения к значению.Но вы можете настроить процесс на произвольную величину, например, 1,5 кадра, и создать взвешенное значение, где это необходимо.

Предположим, данные следующие:

  1. 0,5
  2. 0,8
  3. 0,2
  4. -0,1
  5. -0,5
  6. -0,7

Ваши данные воспроизведения (для 1,5скорость) будет

  1. 0,5
  2. (0,8 + 0,2) / 2
  3. -0,1
  4. (- 0,5 + -0,7) / 2

Я знаю, что были сообщения, которые более полно объясняют этот алгоритм раньше в переполнении стека.Простите, что не выследил их.

Я использую этот метод, чтобы разрешить в реальном времени изменения скорости воспроизведения .wav в следующей библиотеке с открытым исходным кодом: AudioCue .Не стесняйтесь проверить код и использовать идеи в нем.

Ниже описан метод, который создает стереопару звуковых значений из точки, которая находится между двумя звуковыми кадрами (данные представляют собой числа с плавающей запятой в диапазоне от -1 до 1).Это из внутреннего класса AudioCuePlayer в AudioCue.java.Наверное, не самый простой для чтения.Считываемые звуковые данные находятся в массиве cue, а idx является текущим местоположением "головки воспроизведения", которое проходит через этот массив.intIndex - это аудио кадр, а flatIndex - фактическое расположение кадра в массиве.Я использую кадры для отслеживания местоположения точки воспроизведения и вычисления весов интерполяции, а затем использую flatIndex для получения соответствующих значений из массива.

private float[] readFractionalFrame(float[] audioVals, float idx)
{
    final int intIndex = (int) idx;
    final int flatIndex = intIndex * 2;

    audioVals[0] = cue[flatIndex + 2] * (idx - intIndex) 
            + cue[flatIndex] * ((intIndex + 1) - idx);

    audioVals[1] = cue[flatIndex + 3] * (idx - intIndex) 
            + cue[flatIndex + 1] * ((intIndex + 1) - idx);

    return audioVals;
}

Я был бы рад уточнить, если есть вопросы.

0 голосов
/ 30 сентября 2018

Здесь у нас есть метод, который изменяет скорость - удваивая частоту дискретизации.В основном это следующие шаги:

  • открыть аудиопоток файла
  • получить формат
  • создать новый формат с измененной частотой дискретизации
  • открыть строку данных в этом формате
  • , прочитать из файла / аудиопотока и воспроизвести на этой строке

Здесь используются следующие понятия: SourceDataLine, AudioFormat и AudioInputStream.Если вы посмотрите учебник javax.sound, вы найдете их или даже страницы классов.Теперь вы можете создать свой собственный метод (например, настроить (фактор)), который просто получает новый формат, а все остальное остается прежним.

  public void play() {
    try {
      File fileIn = new File(" ....);
      AudioInputStream audioInputStream=AudioSystem.getAudioInputStream(fileIn);
      AudioFormat formatIn=audioInputStream.getFormat();
      AudioFormat format=new AudioFormat(formatIn.getSampleRate()*2, formatIn.getSampleSizeInBits(), formatIn.getChannels(), true, formatIn.isBigEndian());
          System.out.println(formatIn.toString());
          System.out.println(format.toString());
      byte[] data=new byte[1024];
      DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, format);
      SourceDataLine line=(SourceDataLine)AudioSystem.getLine(dinfo);
      if(line!=null) {
        line.open(format);
        line.start();
        while(true) {
          int k=audioInputStream.read(data, 0, data.length);
          if(k<0) break;
          line.write(data, 0, k);
        }
        line.stop();
        line.close();
      }
    }
    catch(Exception ex) { ex.printStackTrace(); }
  }
...