/** * 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.sinusoidal.hntm.synthesis; import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import marytts.signalproc.adaptation.prosody.BasicProsodyModifierParams; import marytts.signalproc.analysis.F0TrackerAutocorrelationHeuristic; import marytts.signalproc.analysis.Labels; import marytts.signalproc.analysis.PitchFileHeader; import marytts.signalproc.analysis.PitchReaderWriter; import marytts.signalproc.analysis.RegularizedCepstrumEstimator; import marytts.signalproc.sinusoidal.PeakMatchedSinusoidalSynthesizer; import marytts.signalproc.sinusoidal.SinusoidalTracks; import marytts.signalproc.sinusoidal.hntm.analysis.HntmAnalyzer; import marytts.signalproc.sinusoidal.hntm.analysis.HntmAnalyzerParams; import marytts.signalproc.sinusoidal.hntm.analysis.HntmPlusTransientsSpeechSignal; import marytts.signalproc.sinusoidal.hntm.analysis.HntmSpeechFrame; import marytts.signalproc.sinusoidal.hntm.analysis.HntmSpeechSignal; import marytts.signalproc.sinusoidal.hntm.analysis.HntmSpeechSignalWithContext; import marytts.signalproc.sinusoidal.hntm.modification.HntmProsodyModifier; import marytts.signalproc.sinusoidal.hntm.synthesis.hybrid.HarmonicsToTrackConverter; import marytts.util.data.audio.AudioDoubleDataSource; import marytts.util.data.audio.DDSAudioInputStream; import marytts.util.data.audio.MaryAudioUtils; import marytts.util.io.FileUtils; import marytts.util.math.MathUtils; import marytts.util.signal.SignalProcUtils; import marytts.util.string.StringUtils; /** * Synthesis using harmonics plus noise (and possibly plus transients) model. * * Reference: Stylianou, Y., 1996, "Harmonic plus Noise Models for Speech, combined with Statistical Methods, for Speech and * Speaker Modification", Ph.D. thesis, Ecole Nationale Supérieure des Télécommunications. (Chapter 3, A Harmonic plus Noise * Model, HNM) * * @author Oytun Türk * */ public class HntmSynthesizer { public HntmSynthesizer() { } public HntmSynthesizedSignal synthesize(HntmSpeechSignal hntmSignal, HntmSpeechFrame[] leftContexts, HntmSpeechFrame[] rightContexts, BasicProsodyModifierParams pmodParams, String referenceFile, HntmAnalyzerParams analysisParams, HntmSynthesizerParams synthesisParams) { // this is never used: BasicProsodyModifierParams pmodParamsOrig = new BasicProsodyModifierParams(pmodParams); // Handle time and pitch scaling by adjusting synthesis times HntmSpeechSignalWithContext prosodyModified = HntmProsodyModifier.modify(hntmSignal, leftContexts, rightContexts, pmodParams, analysisParams); // HntmSynthesizedSignal s = new HntmSynthesizedSignal(); if (synthesisParams.harmonicPartSynthesisMethod == HntmSynthesizerParams.LINEAR_PHASE_INTERPOLATION) { // s.harmonicPart = HarmonicPartLinearPhaseInterpolatorSynthesizer.synthesize(prosodyModified.hntmSignal, // analysisParams, synthesisParams, referenceFile); HarmonicPartLinearPhaseInterpolatorSynthesizer hs = new HarmonicPartLinearPhaseInterpolatorSynthesizer( prosodyModified.hntmSignal, analysisParams, synthesisParams, referenceFile); s.harmonicPart = hs.synthesizeAll(); } else if (synthesisParams.harmonicPartSynthesisMethod == HntmSynthesizerParams.CUBIC_PHASE_INTERPOLATION) { // Convert to pure sinusoidal tracks SinusoidalTracks st = HarmonicsToTrackConverter.convert(prosodyModified.hntmSignal, analysisParams); // PeakMatchedSinusoidalSynthesizer ss = new PeakMatchedSinusoidalSynthesizer( prosodyModified.hntmSignal.samplingRateInHz); s.harmonicPart = ss.synthesize(st, false); } // Synthesize noise part if (analysisParams.noiseModel == HntmAnalyzerParams.LPC) { if (synthesisParams.noisePartLpcSynthesisMethod == HntmSynthesizerParams.OVERLAP_ADD_WITH_WINDOWING) s.noisePart = NoisePartWindowedOverlapAddLpcSynthesizer.synthesize(prosodyModified.hntmSignal, analysisParams, synthesisParams); else if (synthesisParams.noisePartLpcSynthesisMethod == HntmSynthesizerParams.LP_FILTER_WITH_POST_HPF_AND_WINDOWING) s.noisePart = NoisePartLpFilterPostHpfLpcSynthesizer.synthesize(prosodyModified.hntmSignal, analysisParams, synthesisParams); } else if (analysisParams.noiseModel == HntmAnalyzerParams.PSEUDO_HARMONIC) s.noisePart = NoisePartPseudoHarmonicSynthesizer.synthesize(prosodyModified.hntmSignal, analysisParams, synthesisParams, referenceFile); else if (analysisParams.noiseModel == HntmAnalyzerParams.WAVEFORM) s.noisePart = NoisePartWaveformSynthesizer.synthesize(prosodyModified.hntmSignal, prosodyModified.leftContexts, prosodyModified.rightContexts, analysisParams); else if (analysisParams.noiseModel == HntmAnalyzerParams.VOICEDNOISE_LPC_UNVOICEDNOISE_WAVEFORM || analysisParams.noiseModel == HntmAnalyzerParams.UNVOICEDNOISE_LPC_VOICEDNOISE_WAVEFORM) { // First synthesize LPC part (voiced regions) if (synthesisParams.noisePartLpcSynthesisMethod == HntmSynthesizerParams.OVERLAP_ADD_WITH_WINDOWING) s.noisePart = NoisePartWindowedOverlapAddLpcSynthesizer.synthesize(prosodyModified.hntmSignal, analysisParams, synthesisParams); else if (synthesisParams.noisePartLpcSynthesisMethod == HntmSynthesizerParams.LP_FILTER_WITH_POST_HPF_AND_WINDOWING) s.noisePart = NoisePartLpFilterPostHpfLpcSynthesizer.synthesize(prosodyModified.hntmSignal, analysisParams, synthesisParams); // Then synthesize waveform part (unvoiced regions) double[] waveformNoisePart = NoisePartWaveformSynthesizer.synthesize(prosodyModified.hntmSignal, leftContexts, rightContexts, analysisParams); s.noisePart = SignalProcUtils.addSignals(s.noisePart, waveformNoisePart); } // // Synthesize transients if (prosodyModified.hntmSignal instanceof HntmPlusTransientsSpeechSignal && ((HntmPlusTransientsSpeechSignal) prosodyModified.hntmSignal).transients != null) s.transientPart = TransientPartSynthesizer.synthesize((HntmPlusTransientsSpeechSignal) prosodyModified.hntmSignal, analysisParams); // s.generateOutput(); return s; } /** * * @param wavFile * wavefile * @param synthesisParams * synthesisParams * @param pScalesArray * pScalesArray * @param pScalesTimes * pScalesTimes * @param tScalesArray * tScalesArray * @param tScalesTimes * tScalesTimes * @throws UnsupportedAudioFileException * UnsupportedAudioFileException * @throws IOException * IOException */ public static void mainSingleFile(String wavFile, HntmSynthesizerParams synthesisParams, float[][] pScalesArray, float[] pScalesTimes, float[][] tScalesArray, float[] tScalesTimes) throws UnsupportedAudioFileException, IOException { // File input AudioInputStream inputAudio = AudioSystem.getAudioInputStream(new File(wavFile)); int samplingRate = (int) inputAudio.getFormat().getSampleRate(); AudioDoubleDataSource signal = new AudioDoubleDataSource(inputAudio); double[] x = signal.getAllData(); x = MathUtils.multiply(x, 32768.0); // // Analysis HntmAnalyzer ha = new HntmAnalyzer(); // String strComment = null; String strComment = "autoMWF"; // strComment = "4500MWF"; HntmAnalyzerParams analysisParams = new HntmAnalyzerParams(); analysisParams.harmonicModel = HntmAnalyzerParams.HARMONICS_PLUS_NOISE; // analysisParams.harmonicModel = HntmAnalyzerParams.HARMONICS_PLUS_TRANSIENTS_PLUS_NOISE; // analysisParams.noiseModel = HntmAnalyzerParams.LPC; // analysisParams.noiseModel = HntmAnalyzerParams.PSEUDO_HARMONIC; //does not work well analysisParams.noiseModel = HntmAnalyzerParams.WAVEFORM; // analysisParams.noiseModel = HntmAnalyzerParams.VOICEDNOISE_LPC_UNVOICEDNOISE_WAVEFORM; // analysisParams.noiseModel = HntmAnalyzerParams.UNVOICEDNOISE_LPC_VOICEDNOISE_WAVEFORM; analysisParams.useHarmonicAmplitudesDirectly = true; analysisParams.harmonicSynthesisMethodBeforeNoiseAnalysis = HntmSynthesizerParams.LINEAR_PHASE_INTERPOLATION; // analysisParams.harmonicSynthesisMethodBeforeNoiseAnalysis= HntmSynthesizerParams.QUADRATIC_PHASE_INTERPOLATION; //does // not work so well // analysisParams.regularizedCepstrumWarpingMethod = // RegularizedCepstrumEstimator.REGULARIZED_CEPSTRUM_WITH_PRE_BARK_WARPING; analysisParams.regularizedCepstrumWarpingMethod = RegularizedCepstrumEstimator.REGULARIZED_CEPSTRUM_WITH_POST_MEL_WARPING; // Synthesis parameters before noise analysis HntmSynthesizerParams synthesisParamsBeforeNoiseAnalysis = new HntmSynthesizerParams(); synthesisParamsBeforeNoiseAnalysis.harmonicPartSynthesisMethod = HntmSynthesizerParams.LINEAR_PHASE_INTERPOLATION; // synthesisParamsBeforeNoiseAnalysis.harmonicPartSynthesisMethod = HntmSynthesizerParams.QUADRATIC_PHASE_INTERPOLATION; // PitchReaderWriter f0 = null; String strPitchFile = StringUtils.modifyExtension(wavFile, ".ptc"); if (FileUtils.exists(strPitchFile)) { f0 = new PitchReaderWriter(strPitchFile); // Arrays.fill(f0.contour, 100.0); } else { // if file does not exist // this default values are from: marytts.tools.voiceimport.AutocorrelationPitchmarker PitchFileHeader params = new PitchFileHeader(); PitchFileHeader tmp = new PitchFileHeader(); params.windowSizeInSeconds = Double.valueOf(tmp.windowSizeInSeconds); params.skipSizeInSeconds = Double.valueOf(tmp.skipSizeInSeconds); params.voicingThreshold = Double.valueOf(tmp.voicingThreshold); params.minimumF0 = Double.valueOf(tmp.minimumF0); params.maximumF0 = Double.valueOf(tmp.maximumF0); F0TrackerAutocorrelationHeuristic pitchDetector = new F0TrackerAutocorrelationHeuristic(params); try { f0 = pitchDetector.pitchAnalyzeWavFile(wavFile, strPitchFile); } catch (UnsupportedAudioFileException e) { System.out.println("Error! Cannot perform pitch detection..."); } } Labels labels = null; String strLabFile = StringUtils.modifyExtension(wavFile, ".lab"); if (analysisParams.harmonicModel == HntmAnalyzerParams.HARMONICS_PLUS_TRANSIENTS_PLUS_NOISE) { if (!FileUtils.exists(strLabFile)) // Labels required for transients analysis (unless we design an automatic // algorithm) { System.out.println("Error! Labels required for transient analysis..."); System.exit(1); } labels = new Labels(strLabFile); } String analysisResultsFile = StringUtils.modifyExtension(wavFile, ".ana"); // String analysisResultsFile = null; // boolean isCopyPitch = true; // boolean isCopyDuration = true; // BasicProsodyModifierParams pmodParams = new BasicProsodyModifierParams(strPitchFile, strLabFile, "d:\\m0318_happy.ptc", // "d:\\d:\\m0318_happy.lab", isCopyPitch, isCopyDuration); //Prosody from a target file // HntmSpeechSignal hnmSignal = null; if (FileUtils.exists(analysisResultsFile)) { System.out.println(" Warning! Analysis file found, skipping actual HNM analysis and reading from file."); System.out.println(" If analysis parameters have changed, delete this file and run the program again!"); hnmSignal = new HntmSpeechSignal(analysisResultsFile, analysisParams.noiseModel); } else hnmSignal = ha.analyze(x, samplingRate, f0, labels, analysisParams, synthesisParamsBeforeNoiseAnalysis, analysisResultsFile); // for (int n = 0; n < pScalesArray.length; n++) { if (hnmSignal != null) { // BasicProsodyModifierParams pmodParams = new BasicProsodyModifierParams(tScalesArray[n], tScalesTimesArray[n], // pScalesArray[n], pScalesTimesArray[n]); //Prosody from modification factors above BasicProsodyModifierParams pmodParams = new BasicProsodyModifierParams(tScalesArray[n], tScalesTimes, pScalesArray[n], pScalesTimes); // Prosody from modification factors above // Synthesis HntmSynthesizer hs = new HntmSynthesizer(); HntmSynthesizedSignal xhat = hs.synthesize(hnmSignal, null, null, pmodParams, wavFile, analysisParams, synthesisParams); // FileUtils.writeTextFile(hnmSignal.getAnalysisTimes(), "d:\\hnmAnalysisTimes2.txt"); // File output DDSAudioInputStream outputAudio = null; String outFileName = null; String strExt = ""; String modelName = ""; if (analysisParams.harmonicModel == HntmAnalyzerParams.HARMONICS_PLUS_NOISE) { if (analysisParams.noiseModel == HntmAnalyzerParams.WAVEFORM) modelName = "hwm"; else modelName = "hnm"; } else if (analysisParams.harmonicModel == HntmAnalyzerParams.HARMONICS_PLUS_TRANSIENTS_PLUS_NOISE) { if (analysisParams.noiseModel == HntmAnalyzerParams.WAVEFORM) modelName = "hwtm"; else modelName = "hwtm"; } if (strComment != null) modelName += "_" + strComment; if (pScalesArray[n][0] != 1.0f) modelName += "_ps" + String.valueOf(pScalesArray[n][0]); if (tScalesArray[n][0] != 1.0f) modelName += "_ts" + String.valueOf(tScalesArray[n][0]); if (synthesisParams.normalizeOutputWav) xhat.output = MathUtils.multiply(xhat.output, MathUtils.absMax(x) / MathUtils.absMax(xhat.output)); outFileName = wavFile.substring(0, wavFile.length() - 4) + "_" + modelName + strExt + ".wav"; MaryAudioUtils.writeWavFile(MathUtils.divide(xhat.output, 32768.0), outFileName, inputAudio.getFormat()); System.out.println("Ouput file: " + outFileName); if (xhat.harmonicPart != null && synthesisParams.writeHarmonicPartToSeparateFile) { outFileName = wavFile.substring(0, wavFile.length() - 4) + "_" + modelName + "Harmonic" + strExt + ".wav"; if (synthesisParams.normalizeHarmonicPartOutputWav) xhat.harmonicPart = MathUtils.multiply(xhat.harmonicPart, 32768.0 / MathUtils.getAbsMax(xhat.harmonicPart)); MaryAudioUtils .writeWavFile(MathUtils.divide(xhat.harmonicPart, 32768.0), outFileName, inputAudio.getFormat()); } if (xhat.noisePart != null && synthesisParams.writeNoisePartToSeparateFile) { outFileName = wavFile.substring(0, wavFile.length() - 4) + "_" + modelName + "Noise" + strExt + ".wav"; if (synthesisParams.normalizeNoisePartOutputWav) xhat.noisePart = MathUtils.multiply(xhat.noisePart, 32768.0 / MathUtils.getAbsMax(xhat.noisePart)); MaryAudioUtils.writeWavFile(MathUtils.divide(xhat.noisePart, 32768.0), outFileName, inputAudio.getFormat()); } if (xhat.transientPart != null && synthesisParams.writeTransientPartToSeparateFile) { outFileName = wavFile.substring(0, wavFile.length() - 4) + "_" + modelName + "Transient" + strExt + ".wav"; MaryAudioUtils.writeWavFile(MathUtils.divide(xhat.transientPart, 32768.0), outFileName, inputAudio.getFormat()); } if (xhat.harmonicPart != null && synthesisParams.writeOriginalMinusHarmonicPartToSeparateFile) { outFileName = wavFile.substring(0, wavFile.length() - 4) + "_" + modelName + "OrigMinusHarmonic" + strExt + ".wav"; MaryAudioUtils.writeWavFile( MathUtils.divide(SignalProcUtils.addSignals(x, 1.0, xhat.harmonicPart, -1.0), 32768.0), outFileName, inputAudio.getFormat()); } // MaryUtils.plot(xhat.harmonicPart); // MaryUtils.plot(xhat.noisePart); // MaryUtils.plot(y); // if (nEstimate!=null) // { // outFileName = args[0].substring(0, args[0].length()-4) + "_" + modelName + "Diff.wav"; // FileUtils.writeWavFile(new BufferedDoubleDataSource(nEstimate), outFileName, inputAudio.getFormat()); // } // } } System.out.println("Synthesis...done!"); } public static void mainExamplesProsodyModification(String[] args) throws UnsupportedAudioFileException, IOException { // Synthesis parameters HntmSynthesizerParams synthesisParams = new HntmSynthesizerParams(); synthesisParams.harmonicPartSynthesisMethod = HntmSynthesizerParams.LINEAR_PHASE_INTERPOLATION; // synthesisParams.harmonicPartSynthesisMethod = HntmSynthesizerParams.QUADRATIC_PHASE_INTERPOLATION; synthesisParams.overlappingHarmonicPartSynthesis = false; synthesisParams.harmonicSynthesisOverlapInSeconds = 0.010f; /* to output just one file */ synthesisParams.writeHarmonicPartToSeparateFile = false; synthesisParams.writeNoisePartToSeparateFile = false; synthesisParams.writeTransientPartToSeparateFile = false; synthesisParams.writeOriginalMinusHarmonicPartToSeparateFile = false; /* Just time variation: accelerate at the beginning and slows down at the end */ float[][] pScalesArray = new float[1][8]; float[][] tScalesArray = new float[1][8]; pScalesArray[0][0] = 1.0f; tScalesArray[0][0] = 0.1f; pScalesArray[0][1] = 1.0f; tScalesArray[0][1] = 0.2f; pScalesArray[0][2] = 1.0f; tScalesArray[0][2] = 0.3f; pScalesArray[0][3] = 1.0f; tScalesArray[0][3] = 0.4f; pScalesArray[0][4] = 1.0f; tScalesArray[0][4] = 1.6f; pScalesArray[0][5] = 1.0f; tScalesArray[0][5] = 1.8f; pScalesArray[0][6] = 1.0f; tScalesArray[0][6] = 2.0f; pScalesArray[0][7] = 1.0f; tScalesArray[0][7] = 2.2f; float[] pScalesTimes = { 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.3f }; float[] tScalesTimes = { 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.3f }; mainSingleFile(args[0], synthesisParams, pScalesArray, pScalesTimes, tScalesArray, tScalesTimes); /* Just pitch variation: tone normal al the begining and very high at the end */ pScalesArray = new float[1][8]; tScalesArray = new float[1][8]; pScalesArray[0][0] = 1.0f; tScalesArray[0][0] = 1.0f; pScalesArray[0][1] = 2.0f; tScalesArray[0][1] = 1.0f; pScalesArray[0][2] = 3.0f; tScalesArray[0][2] = 1.0f; pScalesArray[0][3] = 4.0f; tScalesArray[0][3] = 1.0f; pScalesArray[0][4] = 5.0f; tScalesArray[0][4] = 1.0f; pScalesArray[0][5] = 6.0f; tScalesArray[0][5] = 1.0f; pScalesArray[0][6] = 7.0f; tScalesArray[0][6] = 1.0f; pScalesArray[0][7] = 8.0f; tScalesArray[0][7] = 1.0f; // apply to the same Scalestimes mainSingleFile(args[0], synthesisParams, pScalesArray, pScalesTimes, tScalesArray, tScalesTimes); /* tone low at the beginning and normal at the end */ pScalesArray[0][0] = 0.3f; tScalesArray[0][0] = 1.0f; pScalesArray[0][1] = 0.4f; tScalesArray[0][1] = 1.0f; pScalesArray[0][2] = 0.5f; tScalesArray[0][2] = 1.0f; pScalesArray[0][3] = 0.6f; tScalesArray[0][3] = 1.0f; pScalesArray[0][4] = 0.7f; tScalesArray[0][4] = 1.0f; pScalesArray[0][5] = 0.8f; tScalesArray[0][5] = 1.0f; pScalesArray[0][6] = 0.9f; tScalesArray[0][6] = 1.0f; pScalesArray[0][7] = 1.0f; tScalesArray[0][7] = 1.0f; // apply to the same Scalestimes mainSingleFile(args[0], synthesisParams, pScalesArray, pScalesTimes, tScalesArray, tScalesTimes); /* * No need to have the same length for modifications of pitch and time start: normal tone, fast, end: high tone, slow */ float[][] pScalesArray1 = new float[1][4]; float[][] tScalesArray1 = new float[1][2]; pScalesArray1[0][0] = 1.0f; tScalesArray1[0][0] = 0.5f; pScalesArray1[0][1] = 2.0f; tScalesArray1[0][1] = 3.5f; pScalesArray1[0][2] = 3.0f; pScalesArray1[0][3] = 4.0f; float[] pScalesTimes1 = { 0.3f, 0.5f, 0.9f, 1.3f }; float[] tScalesTimes1 = { 0.7f, 1.3f }; mainSingleFile(args[0], synthesisParams, pScalesArray1, pScalesTimes1, tScalesArray1, tScalesTimes1); /* */ float[][] pScalesArray2 = new float[1][1]; float[][] tScalesArray2 = new float[1][1]; pScalesArray2[0][0] = 0.5f; tScalesArray2[0][0] = 1.5f; float[] pScalesTimes2 = { 0.7f }; float[] tScalesTimes2 = { 1.3f }; mainSingleFile(args[0], synthesisParams, pScalesArray2, pScalesTimes2, tScalesArray2, tScalesTimes2); // Time invariant case, only one modification set float[][] pScalesArray3 = new float[1][1]; float[][] tScalesArray3 = new float[1][1]; pScalesArray3[0][0] = 1.0f; tScalesArray3[0][0] = 1.0f; float[] pScalesTimes3 = null; float[] tScalesTimes3 = null; mainSingleFile(args[0], synthesisParams, pScalesArray3, pScalesTimes3, tScalesArray3, tScalesTimes3); } /** * * @param args * directory containig .wav files or a wav file, in the same directory it should be a .ptc file that can be * extracted with * @throws UnsupportedAudioFileException * UnsupportedAudioFileException * @throws IOException * IOException */ public static void mainProcessDirOrFile(String[] args) throws UnsupportedAudioFileException, IOException { // Synthesis parameters HntmSynthesizerParams synthesisParams = new HntmSynthesizerParams(); synthesisParams.harmonicPartSynthesisMethod = HntmSynthesizerParams.LINEAR_PHASE_INTERPOLATION; // synthesisParams.harmonicPartSynthesisMethod = HntmSynthesizerParams.QUADRATIC_PHASE_INTERPOLATION; synthesisParams.overlappingHarmonicPartSynthesis = false; synthesisParams.harmonicSynthesisOverlapInSeconds = 0.010f; float[][] pScalesArray = new float[1][8]; float[][] tScalesArray = new float[1][8]; pScalesArray[0][0] = 1.0f; tScalesArray[0][0] = 1.0f; pScalesArray[0][1] = 0.8f; tScalesArray[0][1] = 1.0f; pScalesArray[0][2] = 1.6f; tScalesArray[0][2] = 1.0f; pScalesArray[0][3] = 1.0f; tScalesArray[0][3] = 0.7f; pScalesArray[0][4] = 1.0f; tScalesArray[0][4] = 1.6f; pScalesArray[0][5] = 1.0f; tScalesArray[0][5] = 2.3f; pScalesArray[0][6] = 2.3f; tScalesArray[0][6] = 1.0f; pScalesArray[0][7] = 0.6f; tScalesArray[0][7] = 1.0f; float[] pScalesTimes = { 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.3f }; float[] tScalesTimes = { 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.3f }; if (FileUtils.isDirectory(args[0])) // Process folder { String[] fileList = FileUtils.getFileList(args[0], "wav"); if (fileList != null) { for (int i = 0; i < fileList.length; i++) { mainSingleFile(fileList[i], synthesisParams, pScalesArray, pScalesTimes, tScalesArray, tScalesTimes); System.out.println("HNM processing completed for file " + String.valueOf(i + 1) + " of " + String.valueOf(fileList.length)); } } else System.out.println("No wav files found!"); } else // Process file mainSingleFile(args[0], synthesisParams, pScalesArray, pScalesTimes, tScalesArray, tScalesTimes); } public static void main(String[] args) throws UnsupportedAudioFileException, IOException { // pass as parameter a directory containing wav files or a wav file // mainProcessDirOrFile(args); // Process file, pass as parameter a wav file mainExamplesProsodyModification(args); } }