2012-03-16 13 views
3

私は基礎を作りました。ただし、出力ファイルはWAVヘッダーバイトを何度も何度も繰り返すだけです。結果として得られるファイルは正しいサイズですが、迷惑メールでファイルされます。JavaサウンドAPIを使用した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時間前にこれを理解しようとしていて、私の心は少し揚げられています。だから、何かが意味をなさないのであれば、自由に説明してください。私はファイルを解析したくないが、もし私がしなければならない。

答えて

1

Heh、whoops! 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

私は完全にはわかりませんが、read()関数のオーバーライドも追加する必要があるようです。 いくつかのIDEが関数がオーバーライドされたかのように自動的に動作するかもしれないので、私は完全にはわかりませんと言った理由です。私の修正を適用し、それが動作するかどうかを確認します。

+0

'@ Override'は、私のIDEが他の機能で自動的に追加した単なる注釈です。最終版の一貫性のために注釈を追加しました。 – Knyri

関連する問題