public override WAVSound GenerateWord(string word)
        {
            int      wordIndex = wordToSoundMappingList.FindIndex(m => m.Word == word);
            WAVSound wordSound = null;

            if (wordIndex >= 0)
            {
                WordToSoundMapping wordToSoundMapping = wordToSoundMappingList[wordIndex];
                List <WAVSound>    wavSoundList       = new List <WAVSound>();
                foreach (string soundName in wordToSoundMapping.SoundNameList)
                {
                    FormantSpecification formantSpecification = SpecificationList.Find(s => s.Name == soundName);
                    if (formantSpecification != null)
                    {
                        formantSpecification.GenerateSettingsSequence();
                        WAVSound sound = GenerateSound(formantSpecification);
                        wavSoundList.Add(sound);
                    }
                }
                if (wavSoundList.Count > 0)
                {
                    wordSound = WAVSound.Join(wavSoundList, null);
                }
            }
            return(wordSound);
        }
Exemple #2
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);
        }
        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);
        }