MP3にフィルタをかけて鳴らす

id:m-hashimotoががんばってたので。
FIR型のローパスフィルタをかけてみました。
同じくMP3SPIを使ってます。
フィルタのところをひとつ置きに符号を変えるとハイパスフィルタになって低音がカットされます。

double[] filter = {
     1.247373789136473e-18,
     1.270350182429102e-02,
     2.481243022283666e-02,
    -6.381419731491804e-02,
    -2.761351394755998e-01,
     6.000000000000000e-01,
    -2.761351394755998e-01,
    -6.381419731491804e-02,
     2.481243022283666e-02,
     1.270350182429102e-02,
     1.247373789136473e-18};        


フィルタ係数の設計などは、ここなんかが使えるかもしれません。今回のサンプルでは、11段Hamming窓、正規化遮断周波数0.2のローパスフィルタの値を使っています。
DF-Designとは?

//MP3.java
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class Mp3 {

    public static void main(String[] args) {
        InputStream is = Mp3.class.getResourceAsStream("/test.mp3");

        AudioInputStream in = null;
        AudioInputStream din = null;
        try {
            in = AudioSystem.getAudioInputStream(is);
            AudioFormat format = in.getFormat();

            AudioFormat decodedFormat = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    format.getSampleRate(),
                    16,
                    format.getChannels(),
                    format.getChannels() * 2,
                    format.getSampleRate(),
                    false);

            din = AudioSystem.getAudioInputStream(decodedFormat, in);

            DataLine.Info info =
                    new DataLine.Info(SourceDataLine.class, decodedFormat);
            SourceDataLine line =
                    (SourceDataLine) AudioSystem.getLine(info);
            line.open(decodedFormat);
            line.start();

            byte[] data = new byte[4];
            //ローパスフィルタ
            double[] filter = {
                -1.247373789136473e-18,
                 1.270350182429102e-02,
                -2.481243022283666e-02,
                -6.381419731491804e-02,
                 2.761351394755998e-01,
                 6.000000000000000e-01,
                 2.761351394755998e-01,
                -6.381419731491804e-02,
                -2.481243022283666e-02,
                 1.270350182429102e-02,
                -1.247373789136473e-18};        
            
            int[] left = new int[filter.length];
            int[] right = new int[filter.length];
            while (din.read(data, 0, data.length) != -1) {
                //データ読み込み
                left[0] = data[1] * 256 + data[0];
                right[0] = data[3] * 256 + data[2];
                //フィルタをかける
                double lout = 0;
                double rout = 0;
                for(int i = 0; i < filter.length; ++i){
                    lout += left[i] * filter[i];
                    rout += right[i] * filter[i];
                }
                //出力
                int l = (int) lout;
                int r = (int) rout;
                data[1] = (byte) (l / 256);
                data[0] = (byte) (l % 256);
                data[3] = (byte) (r / 256);
                data[2] = (byte) (r % 256);
                line.write(data, 0, data.length);

                //データをひとつずらす
                for(int i = filter.length - 1; i >= 1; --i){
                    left[i] = left[i - 1];
                    right[i] = right[i - 1];
                }
            }

            line.drain();
            line.stop();
            line.close();

            in.close();
            din.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}