/** * 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 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; /** * This class implements the complementary filter bank used in [Levine, et. al., 1999] for multiresolution sinusoidal modeling. * The filter bank consists of a collection of filter channels (See ComplementaryFilterChannel.java for details). * * [Levine, et. al., 1999] Levine, S. N., Verma, T. S., and Smith III, J. O., "Multiresolution sinusoidal modeling for wideband * audio with modifications", in Proc. of the IEEE ICASSP 1998, Volume 6, Issue , 12-15 May 1998, pp. 3585-3588. * * @author Oytun Türk */ public class ComplementaryFilterBankAnalyser extends FilterBankAnalyserBase { public int numLevels; public int numBands; // We always have 2^numLevels subbands public int baseFilterOrder; protected ComplementaryFilterBankChannelAnalyser[] channelAnalysers; protected double originalEnergy; public ComplementaryFilterBankAnalyser(int numLevelsIn, int baseFilterOrderIn) { if (numLevelsIn >= 0) { numLevels = numLevelsIn; numBands = (int) Math.pow(2.0, numLevels); channelAnalysers = new ComplementaryFilterBankChannelAnalyser[numLevels]; baseFilterOrder = baseFilterOrderIn; int N = baseFilterOrder; for (int i = 0; i < numLevels; i++) { channelAnalysers[i] = new ComplementaryFilterBankChannelAnalyser(N); N = (int) (N * 0.5); } } } public Subband[] apply(double[] x, int samplingRateInHz) { Subband[] subbands = null; int i; originalEnergy = SignalProcUtils.energy(x); // Multiresolution analysis channelAnalysers[0].apply(x); for (i = 1; i < numLevels; i++) channelAnalysers[i].apply(channelAnalysers[i - 1].lpfOut); // // Rearrange results from lower to higher frequencies subbands = new Subband[numLevels + 1]; int currentSamplingRate = (int) (samplingRateInHz / Math.pow(2.0, numLevels)); double startFreqInHz = 0.0; double endFreqInHz = 0.5 * currentSamplingRate; int subbandInd = 0; subbands[subbandInd++] = new Subband(channelAnalysers[numLevels - 1].lpfOut, currentSamplingRate, startFreqInHz, endFreqInHz); startFreqInHz = endFreqInHz; for (i = numLevels; i >= 1; i--) { currentSamplingRate = 2 * currentSamplingRate; endFreqInHz = 0.5 * currentSamplingRate; subbands[subbandInd++] = new Subband(channelAnalysers[i - 1].hpfOut, currentSamplingRate, startFreqInHz, endFreqInHz); startFreqInHz = endFreqInHz; } // 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 numLevels = 4; int N = 512; ComplementaryFilterBankAnalyser analyser = new ComplementaryFilterBankAnalyser(numLevels, N); Subband[] subbands = analyser.apply(x, samplingRate); DDSAudioInputStream outputAudio; AudioFormat outputFormat; String outFileName; // Write highpass components 0 to numLevels-1 for (int 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) + "_sb" + String.valueOf(i + 1) + ".wav"; AudioSystem.write(outputAudio, AudioFileFormat.Type.WAVE, new File(outFileName)); } } }