예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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;
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 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") });
 }
예제 #7
0
 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);
        }