public bool AddPhoneme(PhonemeContainer phoneme)
        {
            //First phoneme added?
            if (this.buffer.Count == 0)
            {
                this.firstStartTime = phoneme.Start;
            }

            //Find largest possible time within the buffer.
            if (phoneme.End >= this.lastEndTime)
            {
                this.lastEndTime = phoneme.End;
            }

            //how long is this buffer in local time.
            float timeRange = this.lastEndTime - this.firstStartTime;

            //All buffers track their own size.
            this.currentBufferLength = timeRange;

            if (timeRange >= this.bufferLength)
            {
                this.buffer.Add(phoneme);
                return(true);
            }

            this.buffer.Add(phoneme);
            return(false);
        }
    public void AddPhoneme(PhonemeContainer phoneme)
    {
        //Debug.Log ("Unity: Phoneme is: " + phoneme.Phoneme + "\n with start: " + phoneme.Start + "\n with stop: " + phoneme.End);

        if (this.currentBuffer != null)
        {
            //This buffer tracks all phonemes added while recording. Do not touch!
            this.completeBuffer.AddPhoneme(phoneme);

            //Check if current buffer is full (timespan of phonemes is greater than bufferlength set when created)
            bool shouldSwap = this.currentBuffer.AddPhoneme(phoneme);

            if (shouldSwap)
            {
                //Debug.Log (this.CurrentBuffer.GetBufferID());

                if (this.OnBufferChanged != null)
                {
                    //By sending the current buffer,
                    //we allow the caller to get all the subsequent buffers from there using its next pointer.
                    this.OnBufferChanged(this.currentBuffer);
                }

                SwapBuffers();
            }
        }
    }
 public void AddPhonemeToBuffer(PhonemeContainer phoneme)
 {
     lock (this.locker)
     {
         //Make sure these always get processed on main thread.
         if (this.eventQueue != null)
         {
             this.eventQueue.Enqueue(phoneme);
         }
     }
 }
Example #4
0
    void RetimeBufferData(List <PhonemeContainer> bufferData, float startTime, List <PhonemeContainer> mergeBuffer)
    {
        for (int i = 0; i < bufferData.Count; i++)
        {
            PhonemeContainer phoneme = bufferData[i];

            //Retime the phoneme.
            phoneme.Start = phoneme.Start - startTime;
            phoneme.End   = phoneme.End - startTime;

            mergeBuffer.Add(phoneme);
        }
    }
        public void TrimBufferSilence(bool padding, float paddingTime)
        {
            //assume total silence, aka first index.
            int stopIndex = 0;

            //Trim silence from end until we meet a phoneme.
            for (int i = this.buffer.Count - 1; i >= 0; i--)
            {
                PhonemeContainer phoneme = this.buffer[i];

                if (string.CompareOrdinal(phoneme.Phoneme, "sil") != 0)
                {
                    //Always use the index ahead of current.
                    stopIndex = i;
                    break;
                }
            }

            //New trimmed buffer will be stop index plus one because otherwise we add one to few becuase of zero based index.
            //Add another 4 phonemes of silence at the end as well.
            List <PhonemeContainer> trimmedBuffer = new List <PhonemeContainer>(stopIndex + 1 + 4);

            if (stopIndex > 0)
            {
                for (int i = 0; i <= stopIndex; i++)
                {
                    trimmedBuffer.Add(this.buffer[i]);
                }

                //Replace buffer with trimmed version.
                this.buffer = trimmedBuffer;

                //Update our range values.
                this.firstStartTime = this.buffer[0].Start;
                this.lastEndTime    = this.buffer[this.buffer.Count - 1].End;

                //Add silence phonemes at the end as a sort of padding
                if (padding)
                {
                    //Padd from the last phoeneme endtime to ensure contineous time.
                    //This routine also takes care of adjusting the current length of the buffer.
                    SetDefaultValues(this.buffer[this.buffer.Count - 1].End, paddingTime, 4);
                }
            }
            else
            {
                this.currentBufferLength = 0f;
                this.buffer = new List <PhonemeContainer>();
            }
        }
    public static void PhonemeCallback(IntPtr phonemeDataPointer)
    {
        if (phonemeDataPointer != IntPtr.Zero)
        {
            PhonemeContainer phoneme = (PhonemeContainer)Marshal.PtrToStructure(phonemeDataPointer, typeof(PhonemeContainer));

            if (Instance != null)
            {
                //Debug.Log ("Phoneme is: " + phoneme.Phoneme);
                //Add last generated phoneme to our front buffer.
                Instance.AddPhonemeToBuffer(phoneme);
            }
        }
    }
        //Check epsilon if needed
        public void SetDefaultValues(float startTime, float timeSpan, int numberOfPhonemes)
        {
            float timeStep = timeSpan / numberOfPhonemes;

            for (int i = 0; i < numberOfPhonemes; i++)
            {
                PhonemeContainer silence = new PhonemeContainer();
                silence.Phoneme = "sil";
                silence.Start   = startTime;
                silence.End     = startTime + timeStep;
                startTime      += timeStep;

                AddPhoneme(silence);
            }
        }
Example #8
0
    void DebugBuffer(PhonemeBuffer.InternalBuffer buffer)
    {
                #if UNITY_EDITOR
        List <PhonemeContainer> phonemes = buffer.GetBufferData();

        Debug.Log("-----Buffer Start----");
        for (int i = 0; i < phonemes.Count; i++)
        {
            PhonemeContainer phoneme = phonemes[i];

            Debug.Log("Phoneme: " + phoneme.Phoneme);
            Debug.Log("Start: " + phoneme.Start);
            Debug.Log("End: " + phoneme.End);
        }
                #endif
    }
    public void Update()
    {
        if (this.eventQueue == null)
        {
            return;
        }

        while (this.eventQueue.Count > 0)
        {
            PhonemeContainer phoneme = this.eventQueue.Dequeue();

            if (this.phonemeBuffer != null)
            {
                this.phonemeBuffer.AddPhoneme(phoneme);
            }
        }
    }
    public void StreamedTextToSpeech(List <PhonemeContainer> phonemes, float streamOffset)
    {
        if (phonemes.Count > 0)
        {
            this.tracks = PhoneDefines.FillTracks();
            this.parMap = ParMap.FillMap();

            for (int i = 0; i < phonemes.Count; i++)
            {
                PhonemeContainer phoneme = phonemes[i];

                //Push phoneme data into tracks.
                AddSym(phoneme.Phoneme, (int)(phoneme.Start * 1000.0f));
            }

            for (int i = 0; i < this.tracks.Count; i++)
            {
                Track track = this.tracks[i];
                track.PushPointsToVector();
            }

            //Define time when to stop calculating.
            float time = phonemes[phonemes.Count - 1].End + LipFadeOutTime;

            //Make sure frame spacing is in 30fps.
            float step = (1000.0f / 30.0f);

            //Scale to milliseconds.
            streamOffset = streamOffset * 1000.0f;

            for (float t = 0; t < (float)(time * 1000); t += step)
            {
                //Matrix row for this frame.
                List <float> animationFrame = GetFrame(t);

                //If time is less than streamoffset dont append new animation data into channels.
                if (t < streamOffset)
                {
                    continue;
                }

                //Reference go animation frame output.
                //0 = Mid_Head_Jnt_03
                //1 = Corner_In >= 0      1 = I < 0
                //2 = lowerLipLifter >= 0   lowerLipLowerer < 0
                //3 = upperLipLowerer >= 0 upperLipLifter < 0

                float jaw = animationFrame[0] + 1.0f;

                jaw = Mathf.Lerp(3.0f, -5f, Mathf.Abs(jaw));

                float WQ       = animationFrame[1] * 100f;
                float lowerLip = animationFrame[2] * 100f;
                float upperLip = animationFrame[3] * 100f;

                this.jawChannel.AddKeyframe(new Vector3(0f, 0f, jaw));

                if (WQ >= 0f)
                {
                    this.cornerinChannel.AddKeyframe(WQ);
                }
                else
                {
                    this.cornerinChannel.AddKeyframe(0f);
                }

                if (WQ < 0f)
                {
                    this.iChannel.AddKeyframe(WQ * 0.75f);
                }
                else
                {
                    this.iChannel.AddKeyframe(0f);
                }

                if (lowerLip >= 0f)
                {
                    this.lowerUpChannel.AddKeyframe(lowerLip * 1.1f);
                }
                else
                {
                    this.lowerUpChannel.AddKeyframe(0f);
                }

                if (lowerLip < 0f)
                {
                    this.lowerDownChannel.AddKeyframe(lowerLip);
                }
                else
                {
                    this.lowerDownChannel.AddKeyframe(0f);
                }

                if (upperLip >= 0f)
                {
                    this.upperDownChannel.AddKeyframe(upperLip);
                }
                else
                {
                    this.upperDownChannel.AddKeyframe(0f);
                }

                if (upperLip < 0f)
                {
                    this.upperUpChannel.AddKeyframe(upperLip);
                }
                else
                {
                    this.upperUpChannel.AddKeyframe(0f);
                }
            }
        }
    }