public FormantSettings Copy() { FormantSettings copiedFormantSettings = new FormantSettings(); copiedFormantSettings.Duration = this.duration; copiedFormantSettings.VoicedFraction = this.voicedFraction; copiedFormantSettings.TransitionStart = this.transitionStart; copiedFormantSettings.FrequencyList = new List <double>(); foreach (double frequency in this.frequencyList) { copiedFormantSettings.FrequencyList.Add(frequency); } copiedFormantSettings.AmplitudeList = new List <double>(); foreach (double amplitude in this.amplitudeList) { copiedFormantSettings.AmplitudeList.Add(amplitude); } copiedFormantSettings.BandwidthList = new List <double>(); foreach (double bandwidth in this.bandwidthList) { copiedFormantSettings.BandwidthList.Add(bandwidth); } copiedFormantSettings.RelativePitchVariationParameterList = new List <double>(); foreach (double pitchVariationParameter in this.relativePitchVariationParameterList) { copiedFormantSettings.RelativePitchVariationParameterList.Add(pitchVariationParameter); } copiedFormantSettings.RelativeAmplitudeVariationParameterList = new List <double>(); foreach (double amplitudeVariationParameter in this.relativeAmplitudeVariationParameterList) { copiedFormantSettings.RelativeAmplitudeVariationParameterList.Add(amplitudeVariationParameter); } return(copiedFormantSettings); }
public FormantSettings GetInterpolatedSettings(int sampleIndex) { int settingsIndex = settingsIndexList[sampleIndex]; if ((formantSettingsList[settingsIndex].TransitionStart >= 1.0) || (formantSettingsList.Count == 1)) { return(formantSettingsList[settingsIndex]); } // Common special case.. else { double deltaTime = deltaTimeList[sampleIndex]; double constantSettingsEndTime = formantSettingsList[settingsIndex].TransitionStart * formantSettingsList[settingsIndex].Duration; if (deltaTime <= constantSettingsEndTime) // Before transition onset { return(formantSettingsList[settingsIndex]); } else // After transition onset { int nextSettingsIndex = settingsIndex; if (settingsIndex < (formantSettingsList.Count - 1)) { nextSettingsIndex = settingsIndex + 1; } double alpha = (deltaTime - constantSettingsEndTime) / (formantSettingsList[settingsIndex].Duration - constantSettingsEndTime); FormantSettings settings = FormantSettings.Interpolate(formantSettingsList[settingsIndex], formantSettingsList[nextSettingsIndex], alpha); return(settings); } } }
public void GenerateSettingsSequence() { double sampleTime = 1 / (double)samplingFrequency; double duration = GetDuration(); int numberOfSamples = (int)Math.Round(duration / sampleTime); double time = 0; int currentIndex = 0; settingsIndexList = new List <int>(); deltaTimeList = new List <double>(); FormantSettings currentFormantSettings = formantSettingsList[currentIndex]; double currentIndexStartTime = time; for (int ii = 0; ii < numberOfSamples; ii++) { settingsIndexList.Add(currentIndex); time = ii * sampleTime; deltaTimeList.Add(time - currentIndexStartTime); if ((time - currentIndexStartTime) > currentFormantSettings.Duration) { currentIndex++; currentFormantSettings = formantSettingsList[currentIndex]; currentIndexStartTime = time; } } }
public FormantSpecification Copy() { FormantSpecification copiedFormantSpecification = new FormantSpecification(this.fundamentalFrequency, this.samplingFrequency); foreach (FormantSettings formantSettings in this.formantSettingsList) { FormantSettings copiedFormantSettings = formantSettings.Copy(); copiedFormantSpecification.FormantSettingsList.Add(copiedFormantSettings); } return(copiedFormantSpecification); }
public static FormantSettings Interpolate(FormantSettings settings1, FormantSettings settings2, double alpha) { FormantSettings interpolatedSettings = settings1.Copy(); // Easy way to get the correct number of sinusoids etc. // The Duration and TransitionStart parameters should NOT be interpolated, and neither should // the amplitude and pitch variation parameters (which are interpolated separately, see the FormantSpecification class. // ...but the remaining parameters should: interpolatedSettings.VoicedFraction = (1 - alpha) * settings1.VoicedFraction + alpha * settings2.VoicedFraction; for (int iSinusoid = 0; iSinusoid < settings1.AmplitudeList.Count; iSinusoid++) { interpolatedSettings.AmplitudeList[iSinusoid] = (1 - alpha) * settings1.AmplitudeList[iSinusoid] + alpha * settings2.AmplitudeList[iSinusoid]; interpolatedSettings.FrequencyList[iSinusoid] = (1 - alpha) * settings1.FrequencyList[iSinusoid] + alpha * settings2.FrequencyList[iSinusoid]; interpolatedSettings.BandwidthList[iSinusoid] = (1 - alpha) * settings1.BandwidthList[iSinusoid] + alpha * settings2.BandwidthList[iSinusoid]; } return(interpolatedSettings); }
public void SetFormantSettings(FormantSettings formantSettings) { this.formantSettings = formantSettings; GenerateColumns(); for (int iSinusoid = 0; iSinusoid < formantSettings.FrequencyList.Count; iSinusoid++) { this.Rows.Add(new string[] { "Frequency" + (iSinusoid + 1).ToString(), formantSettings.FrequencyList[iSinusoid].ToString("0") }); this.Rows.Add(new string[] { "Amplitude" + (iSinusoid + 1).ToString(), formantSettings.AmplitudeList[iSinusoid].ToString("0.000") }); this.Rows.Add(new string[] { "Bandwidth" + (iSinusoid + 1).ToString(), formantSettings.BandwidthList[iSinusoid].ToString("0") }); } this.Rows.Add(new string[] { "Duration", formantSettings.Duration.ToString("0.000") }); this.Rows.Add(new string[] { "Voiced fraction", formantSettings.VoicedFraction.ToString("0.000") }); this.Rows.Add(new string[] { "Transition start", formantSettings.TransitionStart.ToString("0.000") }); this.Rows.Add(new string[] { "Relative amplitude variation (extremum time)", formantSettings.RelativeAmplitudeVariationParameterList[0].ToString("0.000") }); this.Rows.Add(new string[] { "Relative amplitude variation (start amplitude)", formantSettings.RelativeAmplitudeVariationParameterList[1].ToString("0.000") }); this.Rows.Add(new string[] { "Relative amplitude variation (end amplitude)", formantSettings.RelativeAmplitudeVariationParameterList[2].ToString("0.000") }); this.Rows.Add(new string[] { "Relative pitch variation (constant)", formantSettings.RelativePitchVariationParameterList[0].ToString("0.000") }); this.Rows.Add(new string[] { "Relative pitch variation (linear)", formantSettings.RelativePitchVariationParameterList[1].ToString("0.000") }); this.Rows.Add(new string[] { "Relative pitch variation (quadratic)", formantSettings.RelativePitchVariationParameterList[2].ToString("0.000") }); }
public void Clear() { this.formantSettings = null; GenerateColumns(); }
public WAVSound GenerateSound(FormantSpecification formantSpecification) { double duration = formantSpecification.GetDuration(); int samplingFrequency = formantSpecification.SamplingFrequency; double sampleTime = 1.0 / (double)samplingFrequency; double nominalPulsePeriod = 1 / (double)formantSpecification.FundamentalFrequency; int numberOfSamples = (int)Math.Round(duration / sampleTime); // Generate voiced pulse train: This requires running through the sequence // of formantSettings in the formantSpecification, in order to determine // the pitch (and its inverse, the pulse period) at each time: List <int> voicedPulseSpacingList = formantSpecification.GeneratePulseSpacingList(); List <double> voicedPulseTrain = new List <double>(); for (int ii = 0; ii < numberOfSamples; ii++) { voicedPulseTrain.Add(0); } // To be adjusted below. int sampleIndex = 0; while (sampleIndex < voicedPulseTrain.Count) { voicedPulseTrain[sampleIndex] = 1.0; sampleIndex += voicedPulseSpacingList[sampleIndex]; } // Generate unvoiced pulse train: if (randomNumberGenerator == null) { randomNumberGenerator = new Random(); } // if (gaussian == null) { gaussian = new GaussianDistribution(0, 0.05, -1); } List <double> unvoicedPulseTrain = new List <double>(); for (int ii = 0; ii < numberOfSamples; ii++) { unvoicedPulseTrain.Add(0); if (randomNumberGenerator.NextDouble() < 0.5) { unvoicedPulseTrain[ii] = -WHITE_NOISE_LEVEL + 2 * WHITE_NOISE_LEVEL * randomNumberGenerator.NextDouble(); // gaussian.GetSample(); } } // Set up sinusoids: int numberOfSinusoids = formantSpecification.GetNumberOfSinusoids(); List <DampedSinusoid> sinusoidList = new List <DampedSinusoid>(); for (int iSinusoid = 0; iSinusoid < numberOfSinusoids; iSinusoid++) { DampedSinusoid sinusoid = new DampedSinusoid(samplingFrequency); sinusoidList.Add(sinusoid); } // Prepare for storing pitch: if (storePitch) { // pitchList = new List<double>(); timePitchPeriodList = new List <List <double> >(); } // Generate the relative amplitude list: Must be done separately, to handle // transitions: List <double> relativeAmplitudeList = formantSpecification.GenerateRelativeAmplitudeList(); // Generate the unscaled samples: List <double> unscaledSampleList = new List <double>(); double time = 0; sampleIndex = 0; while (sampleIndex < numberOfSamples) { time = sampleIndex * sampleTime; FormantSettings formantSettings = formantSpecification.GetInterpolatedSettings(sampleIndex); for (int iSinusoid = 0; iSinusoid < sinusoidList.Count; iSinusoid++) { sinusoidList[iSinusoid].SetParameters(formantSettings.AmplitudeList[iSinusoid], formantSettings.FrequencyList[iSinusoid], formantSettings.BandwidthList[iSinusoid]); } double x = formantSettings.VoicedFraction * voicedPulseTrain[sampleIndex] + (1 - formantSettings.VoicedFraction) * unvoicedPulseTrain[sampleIndex]; // 20170407 if (storePitch) { if (formantSettings.VoicedFraction > minimumVoicedFractionForPitch) { if (voicedPulseTrain[sampleIndex] != 0) // Define the pitch only at pulse spikes { double pitch = samplingFrequency / voicedPulseSpacingList[sampleIndex]; // pitchList.Add(pitch); double pitchPeriod = voicedPulseSpacingList[sampleIndex] * sampleTime; timePitchPeriodList.Add(new List <double>() { time, pitchPeriod }); } /* else { pitchList.Add(-1); } * } * else * { * pitchList.Add(-1); // < 0 => pitch not defined */ } } double deltaTime = formantSpecification.DeltaTimeList[sampleIndex]; double relativeAmplitude = relativeAmplitudeList[sampleIndex]; // formantSettings.GetRelativeAmplitude(deltaTime); double sample = 0; for (int iSinusoid = 0; iSinusoid < sinusoidList.Count; iSinusoid++) { sample += sinusoidList[iSinusoid].Next(x); } sample *= relativeAmplitude * volume; unscaledSampleList.Add(sample); sampleIndex++; } // Next generate the scaled samples List <Int16> sampleList = new List <Int16>(); for (int ii = 0; ii < numberOfSamples; ii++) { if (unscaledSampleList[ii] > 1) { unscaledSampleList[ii] = 1; } else if (unscaledSampleList[ii] < -1) { unscaledSampleList[ii] = -1; } Int16 sample = (Int16)Math.Round(32767 * unscaledSampleList[ii]); // Some ugly hard-coding here... sampleList.Add(sample); } List <List <Int16> > twoChannelSampleList = new List <List <Int16> >(); twoChannelSampleList.Add(sampleList); WAVSound wavSound = new WAVSound("Test", samplingFrequency, 1, 16); // Some ugly hard-coding here... wavSound.GenerateFromSamples(twoChannelSampleList); return(wavSound); }