Java - понижение частоты дискретизации с 22050 до 8000 дает нулевые байты

Я пытаюсь понизить разрешение аудио .wav с 22050 до 8000 с помощью AudioInputStream, но преобразование возвращает мне 0 байтов данных. Вот код:

AudioInputStream ais;
AudioInputStream eightKhzInputStream = null;
ais = AudioSystem.getAudioInputStream(file);
if (ais.getFormat().getSampleRate() == 22050f) {
    AudioFileFormat sourceFileFormat = AudioSystem.getAudioFileFormat(file);
    AudioFileFormat.Type targetFileType = sourceFileFormat.getType();
    AudioFormat sourceFormat = ais.getFormat();
    AudioFormat targetFormat = new AudioFormat(
        sourceFormat.getEncoding(),
        8000f,
        sourceFormat.getSampleSizeInBits(),
        sourceFormat.getChannels(),
        sourceFormat.getFrameSize(),
        8000f,
        sourceFormat.isBigEndian());
    eightKhzInputStream = AudioSystem.getAudioInputStream(targetFormat, ais);
    int nWrittenBytes = 0;
    nWrittenBytes = AudioSystem.write(eightKhzInputStream, targetFileType, file);

Я уже проверил AudioSystem.isConversionSupported(targetFormat, sourceFormat), и он возвращает true. Есть идеи?


person Claudio Mezzasalma    schedule 12.02.2014    source источник


Ответы (1)


Я только что протестировал ваш код с различными аудиофайлами, и все работает нормально. Я могу только предположить, что вы либо тестируете свой код с пустым аудиофайлом (байты == 0), либо файл, который вы пытаетесь преобразовать, не поддерживается аудиосистемой Java.

Попробуйте использовать другой входной файл и/или преобразовать входной файл в совместимый файл, и он должен работать.

Вот основной метод, который сработал для меня:

public static void main(String[] args) throws InterruptedException, UnsupportedAudioFileException, IOException {
    File file = ...;
    File output = ...;

    AudioInputStream ais;
    AudioInputStream eightKhzInputStream = null;
    ais = AudioSystem.getAudioInputStream(file);
    AudioFormat sourceFormat = ais.getFormat();
    if (ais.getFormat().getSampleRate() == 22050f) {
        AudioFileFormat sourceFileFormat = AudioSystem.getAudioFileFormat(file);
        AudioFileFormat.Type targetFileType = sourceFileFormat.getType();

        AudioFormat targetFormat = new AudioFormat(
                sourceFormat.getEncoding(),
                8000f,
                sourceFormat.getSampleSizeInBits(),
                sourceFormat.getChannels(),
                sourceFormat.getFrameSize(),
                8000f,
                sourceFormat.isBigEndian());
        if (!AudioSystem.isFileTypeSupported(targetFileType) || ! AudioSystem.isConversionSupported(targetFormat, sourceFormat)) {
              throw new IllegalStateException("Conversion not supported!");
        }
        eightKhzInputStream = AudioSystem.getAudioInputStream(targetFormat, ais);
        int nWrittenBytes = 0;

        nWrittenBytes = AudioSystem.write(eightKhzInputStream, targetFileType, output);
        System.out.println("nWrittenBytes: " + nWrittenBytes);
    }
}
person Balder    schedule 12.02.2014
comment
ais указывает на реальный файл: ais. available() возвращает 26000 или около того, и это стандартный файл WAV. В конце концов, если бы формат был неизвестен Java Audio System, я бы получил исключение при запросе AudioInputStream, не так ли? - person Claudio Mezzasalma; 12.02.2014
comment
Да, на самом деле вы должны получить исключение ... в любом случае, ваш код работает на моем компьютере, я опубликую рабочий метод main через секунду. - person Balder; 12.02.2014
comment
Я добавил проверку, действительно ли преобразование поддерживается в коде. Попробуйте и посмотрите, выбрасывается ли IllegalStateException или нет. - person Balder; 12.02.2014
comment
Никаких исключений не выдается, оба теста внутри if возвращают true. - person Claudio Mezzasalma; 12.02.2014
comment
Очень странно... попробуйте загрузить этот аудиофайл: www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples/. Преобразование этого файла определенно работает на моем компьютере. - person Balder; 12.02.2014
comment
Ни в коем случае... должно быть что-то с кодеками, другой причины не могу придумать... - person Claudio Mezzasalma; 13.02.2014
comment
Я не могу в это поверить, но у меня это сработало. В основном я делал ошибки: - Полагаясь на eightKhzInputStream.available, чтобы сказать, что конвертация не удалась - Записывая преобразованную волну в тот же файл, из которого она была прочитана. Это привело к удалению исходного файла, и поэтому ничего не было записано, потому что ничего нельзя было прочитать. Сравнение вашего кода построчно с моим было ключом к пониманию моих ошибок. Спасибо! - person Claudio Mezzasalma; 13.02.2014