前回最大化をするクラスを作りました。今回はこれを利用する側を作ります。こちらは以前に作ったファイル書き出し用のクラスWavFileWriterを修正していきます。
修正内容
コンストラクタ
今まではSoundReadableをそのまま内部で持っていましたがここではMaximizerに変更します。
public class WavFileWriter extends InputStream {
public static final float SAMPLE_RATE = 48000;
boolean signed = true;
boolean big_endian = true;
int sample_size_byte = 2;
ArrayList list;
Maximizer maximizer;
public WavFileWriter(SoundReadable readable) throws IOException {
list = new ArrayList<>();
double volume = Math.pow(2, sample_size_byte * 8 - 1) - 1;
maximizer = new Maximizer(readable, volume);
}
既存メソッドの微修正
次にreadメソッドを直します。今まではSoundReadableから読み込んだ値に最大音量を係数としてかけていましたがMaximizer内部でこの処理は行うのでただ読み込んで返すだけになりました。
@Override
public int read() throws IOException {
if (list.isEmpty()) {
double value = maximizer.read();
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.putLong((long) value);
byte[] array = buffer.array();
for (int i = 8 - sample_size_byte; i < 8; i++) {
list.add(array[i]);
}
}
int ret = Byte.toUnsignedInt(list.remove(0));
return ret;
}
同様に既存のSoundReadableから返す値もMaximizerで置き換えています。
public long length() {
return maximizer.length();
}
public AudioFormat getFormat() {
return new AudioFormat(SAMPLE_RATE, sample_size_byte * 8, maximizer.getChannel(), signed, big_endian);
}
一時ファイルを消すための処理を追加しました。
public void terminate() throws IOException {
maximizer.terminate();
}
mainメソッドの修正
最後にmainメソッドを修正します。とはいっても最後に終了処理を呼び出すだけです。
FrequencyMap freqMap = new FrequencyMap(440.0);
freqMap.putFreq(2.0, 880.0);
WavFileWriter ss = new WavFileWriter(new OscillatorReader(new SineOscillator(), freqMap, 3));
AudioSystem.write(
new AudioInputStream(ss, ss.getFormat(), ss.length()),
AudioFileFormat.Type.WAVE, new File("/Users/minaberger/mywork/sine_440_880.wav"));
ss.terminate();
これで修正は終わりです。これからは音量に気にせず音を合成することができます。
ソース
以下ソースです。
package mocha.sound;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class WavFileWriter extends InputStream {
public static final float SAMPLE_RATE = 48000;
boolean signed = true;
boolean big_endian = true;
int sample_size_byte = 2;
ArrayList list;
Maximizer maximizer;
public WavFileWriter(SoundReadable readable) throws IOException {
list = new ArrayList<>();
double volume = Math.pow(2, sample_size_byte * 8 - 1) - 1;
maximizer = new Maximizer(readable, volume);
}
@Override
public int read() throws IOException {
if (list.isEmpty()) {
double value = maximizer.read();
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.putLong((long) value);
byte[] array = buffer.array();
for (int i = 8 - sample_size_byte; i < 8; i++) {
list.add(array[i]);
}
}
int ret = Byte.toUnsignedInt(list.remove(0));
return ret;
}
public long length() {
return maximizer.length();
}
public AudioFormat getFormat() {
return new AudioFormat(SAMPLE_RATE, sample_size_byte * 8, maximizer.getChannel(), signed, big_endian);
}
public void terminate() throws IOException {
maximizer.terminate();
}
public static void main(String[] arg) throws IOException {
FrequencyMap freqMap = new FrequencyMap(440.0);
freqMap.putFreq(2.0, 880.0);
WavFileWriter ss = new WavFileWriter(new OscillatorReader(new SineOscillator(), freqMap, 3));
AudioSystem.write(
new AudioInputStream(ss, ss.getFormat(), ss.length()),
AudioFileFormat.Type.WAVE, new File("/Users/minaberger/mywork/sine_440_880.wav"));
ss.terminate();
}
}