Обрезать начало и конец из файла WAV с помощью API звука Java - PullRequest
4 голосов
/ 17 марта 2012

У меня есть основы.Однако выходной файл просто повторяет байты заголовка WAV снова и снова.Полученный файл имеет правильный размер, но он заполнен нежелательной.

Я пытаюсь использовать класс, расширяющий AudioInputStream, чтобы я мог беспрепятственно использовать его с другим кодом, который будет смешивать его с другим AudioInputStream (которыйпрекрасно работает).

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

public class TrimmerAIS extends AudioInputStream{

private final AudioInputStream stream;
private final long startByte,endByte;
private long t_bytesRead=0;
public TrimmerAIS(AudioFormat audioFormat,AudioInputStream audioInputStream,long startMilli,long endMilli){
    super(new ByteArrayInputStream(new byte[0]),audioFormat,AudioSystem.NOT_SPECIFIED);
    stream=audioInputStream;
    //startByte=(long)((startMilli/1000f)*stream.getFormat().getSampleRate()*stream.getFormat().getSampleSizeInBits()*stream.getFormat().getChannels())/8;
    //endByte=(long)((endMilli/1000f)*stream.getFormat().getSampleRate()*stream.getFormat().getSampleSizeInBits()*stream.getFormat().getChannels())/8;
    startByte=(long)((startMilli/1000)*stream.getFormat().getFrameRate()*stream.getFormat().getFrameSize());
    endByte=(long)((endMilli/1000)*stream.getFormat().getFrameRate()*stream.getFormat().getFrameSize());
}
private byte[] tempBuffer;

@Override
public int available() throws IOException{
    return (int)(endByte-startByte-t_bytesRead);
}
public int read(byte[] abData,int nOffset,int nLength) throws IOException{
    // set up the temporary byte buffer
    if(tempBuffer==null||tempBuffer.length<nLength){
        tempBuffer=new byte[nLength];
    }
    int bytesRead=0;
    if(t_bytesRead<startByte){
        do{//skip to starting byte
            bytesRead=(int)skip(startByte-t_bytesRead);
            t_bytesRead+=bytesRead;
        }while(t_bytesRead<startByte);
    }
    if(t_bytesRead>=endByte){
        return -1;
    }

    bytesRead=stream.read(tempBuffer,0,nLength);
    if(bytesRead==-1){//premature EOF
        return -1;
    }else if(bytesRead==0){
        return 0;
    }
    t_bytesRead+=bytesRead;
    if(t_bytesRead>=endByte){//correct bytes read to exclude any bytes over the limit
        bytesRead=(int)(bytesRead-(t_bytesRead-endByte));
    }
    return bytesRead;
}
public static void main(String[] args) throws UnsupportedAudioFileException, IOException{
    AudioInputStream music=null;
    music = AudioSystem.getAudioInputStream(new File("music/0.wav"));
    music=new TrimmerAIS(music.getFormat(),music,0,15000);
    AudioSystem.write(music,AudioFileFormat.Type.WAVE,new File("out.wav"));
}
}

Я просто не могу найти в этом ничего плохого.Я нашел похожий пост здесь, который связан с https://forums.oracle.com/forums/thread.jspa?threadID=2136229&tstart=0.. Это то, что делает мой, за исключением того, что вы задаете ему начальную и конечную позиции в миллисекундах, и его можно передавать / оборачивать в другой AIS или выводить безнужно прочитать нужный сегмент в массив и затем записать его.Я пытался понять это в течение последних 3 часов, и мой разум немного жарен.Так что, если что-то не имеет смысла, не стесняйтесь просить разъяснений.Я предпочел бы не анализировать файл, но если мне нужно, я должен.

Ответы [ 2 ]

1 голос
/ 19 марта 2012

Хе, ой! Просто нужно было удалить tempBuffer и заменить его на abData. Был долгий день. Ниже приведен исправленный код. Мысль об удалении этого, так как это была простая ошибка, но единственная причина, по которой я сделал этот класс, состоит в том, что он еще не существует.

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

public class TrimmerAIS extends AudioInputStream{

private final AudioInputStream stream;
private final long startByte,endByte;
private long t_bytesRead=0;

public TrimmerAIS(AudioFormat audioFormat,AudioInputStream audioInputStream,long startMilli,long endMilli){
    super(new ByteArrayInputStream(new byte[0]),audioFormat,AudioSystem.NOT_SPECIFIED);
    stream=audioInputStream;
    //calculate where to start and where to end
    startByte=(long)((startMilli/1000)*stream.getFormat().getFrameRate()*stream.getFormat().getFrameSize());
    endByte=(long)((endMilli/1000)*stream.getFormat().getFrameRate()*stream.getFormat().getFrameSize());
}

@Override
public int available() throws IOException{
    return (int)(endByte-startByte-t_bytesRead);
}
public int read(byte[] abData,int nOffset,int nLength) throws IOException{
    int bytesRead=0;
    if(t_bytesRead<startByte){
        do{
            bytesRead=(int)skip(startByte-t_bytesRead);
            t_bytesRead+=bytesRead;
        }while(t_bytesRead<startByte);
    }
    if(t_bytesRead>=endByte)//end reached. signal EOF
        return -1;

    bytesRead=stream.read(abData,0,nLength);
    if(bytesRead==-1)
        return -1;
    else if(bytesRead==0)
        return 0;

    t_bytesRead+=bytesRead;
    if(t_bytesRead>=endByte)// "trim" the extra by altering the number of bytes read
        bytesRead=(int)(bytesRead-(t_bytesRead-endByte));

    return bytesRead;
}
public static void main(String[] args) throws UnsupportedAudioFileException, IOException{
    AudioInputStream music=null;
    music = AudioSystem.getAudioInputStream(new File("music/0.wav"));
    music=new TrimmerAIS(music.getFormat(),music,0,15000);
    AudioSystem.write(music,AudioFileFormat.Type.WAVE,new File("out.wav"));
}
}
0 голосов
/ 16 июня 2013

Я не совсем уверен, но кажется, что вам нужно добавить переопределение и для функции read ().Причину, по которой я сказал, я не совсем уверен, потому что некоторые IDE могут автоматически работать, как если бы функция была переопределена.Примените мое исправление и посмотрите, работает ли оно, хотя.

...