/** * Copyright 2007 DFKI GmbH. * All Rights Reserved. Use is subject to license terms. * * This file is part of MARY TTS. * * MARY TTS is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package marytts.signalproc.filter; import java.io.File; import java.io.IOException; import java.util.Arrays; 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; import marytts.util.data.BufferedDoubleDataSource; import marytts.util.data.audio.AudioDoubleDataSource; import marytts.util.data.audio.DDSAudioInputStream; import marytts.util.signal.SignalProcUtils; /** * @author Oytun Türk * */ public class FIRWaveletFilterBankAnalyser extends FilterBankAnalyserBase { public FIRFilter[][] filters; public double[][] normalizationFilterTransformedIRs; public int numLevels; double samplingRateInHz; double[] samplingRates; public FIRWaveletFilterBankAnalyser(int numLevelsIn, double samplingRateInHzIn) { numLevels = Math.max(0, numLevelsIn); samplingRateInHz = samplingRateInHzIn; int i, j; samplingRates = new double[numLevels + 1]; samplingRates[0] = 0.5 * samplingRateInHz; for (i = 1; i < numLevels; i++) samplingRates[i] = 0.5 * samplingRates[i - 1]; samplingRates[numLevels] = samplingRates[numLevels - 1]; int filterOrder; int maxFreq; filters = new FIRFilter[numLevels][2]; normalizationFilterTransformedIRs = new double[numLevels][]; for (i = 0; i < numLevels; i++) { filterOrder = SignalProcUtils.getFIRFilterOrder((int) (samplingRates[i])); filters[i][0] = new LowPassFilter(0.25, filterOrder); filters[i][1] = new HighPassFilter(0.25, filterOrder); maxFreq = filters[i][0].transformedIR.length / 2 + 1; normalizationFilterTransformedIRs[i] = new double[maxFreq]; Arrays.fill(normalizationFilterTransformedIRs[i], 0.0); normalizationFilterTransformedIRs[i][0] += Math.abs(filters[i][0].transformedIR[0]); normalizationFilterTransformedIRs[i][0] += Math.abs(filters[i][1].transformedIR[0]); normalizationFilterTransformedIRs[i][maxFreq - 1] += Math.abs(filters[i][0].transformedIR[1]); normalizationFilterTransformedIRs[i][maxFreq - 1] += Math.abs(filters[i][1].transformedIR[1]); for (j = 1; j < maxFreq - 1; j++) { normalizationFilterTransformedIRs[i][j] += Math.sqrt(filters[i][0].transformedIR[2 * j] * filters[i][0].transformedIR[2 * j] + filters[i][0].transformedIR[2 * j + 1] * filters[i][0].transformedIR[2 * j + 1]); normalizationFilterTransformedIRs[i][j] += Math.sqrt(filters[i][1].transformedIR[2 * j] * filters[i][1].transformedIR[2 * j] + filters[i][1].transformedIR[2 * j + 1] * filters[i][1].transformedIR[2 * j + 1]); } for (j = 0; j < maxFreq; j++) normalizationFilterTransformedIRs[i][j] = 1.0 / normalizationFilterTransformedIRs[i][j]; } } public Subband[] apply(double[] x) { Subband[] subbands = null; if (filters != null && x != null && numLevels >= 0) { int i; subbands = new Subband[numLevels + 1]; double[] lowBand = null; double[] highBand = null; int count = 0; for (i = 0; i < numLevels; i++) { if (i == 0) { lowBand = filters[i][0].apply(x); lowBand = SignalProcUtils.decimate(lowBand, 2.0); highBand = filters[i][1].apply(x); highBand = SignalProcUtils.decimate(highBand, 2.0); } else { highBand = filters[i][1].apply(lowBand); highBand = SignalProcUtils.decimate(highBand, 2.0); lowBand = filters[i][0].apply(lowBand); lowBand = SignalProcUtils.decimate(lowBand, 2.0); } subbands[i] = new Subband(highBand, samplingRates[i]); } subbands[numLevels] = new Subband(lowBand, samplingRates[numLevels]); } // return subbands; } public static void main(String[] args) throws UnsupportedAudioFileException, IOException { AudioInputStream inputAudio = AudioSystem.getAudioInputStream(new File(args[0])); int samplingRate = (int) inputAudio.getFormat().getSampleRate(); AudioDoubleDataSource signal = new AudioDoubleDataSource(inputAudio); double[] x = signal.getAllData(); int i; int numLevels = 1; FIRWaveletFilterBankAnalyser analyser = new FIRWaveletFilterBankAnalyser(numLevels, samplingRate); Subband[] subbands = analyser.apply(x); DDSAudioInputStream outputAudio; AudioFormat outputFormat; String outFileName; // Write highpass components 0 to numLevels-1 for (i = 0; i < subbands.length; i++) { outputFormat = new AudioFormat((int) (subbands[i].samplingRate), inputAudio.getFormat().getSampleSizeInBits(), inputAudio.getFormat().getChannels(), true, true); outputAudio = new DDSAudioInputStream(new BufferedDoubleDataSource(subbands[i].waveform), outputFormat); outFileName = args[0].substring(0, args[0].length() - 4) + "_band" + String.valueOf(i + 1) + ".wav"; AudioSystem.write(outputAudio, AudioFileFormat.Type.WAVE, new File(outFileName)); } } }