Пример #1
0
 /// <summary>
 /// cTor: Copy constructor
 /// </summary>
 /// <param name="other"></param>
 public SoundBite(SoundBite other)
 {
     this.Melody    = other.Melody;
     this.Tone      = other.Tone;
     this.Duration  = other.Duration;
     this.Loops     = other.Loops;
     this.Volume    = other.Volume;
     this.SpeedFact = other.SpeedFact;
 }
Пример #2
0
        /// <summary>
        /// Change the sound to play
        /// </summary>
        /// <param name="soundBite">The SoundBite to play from now on</param>
        public void AddSoundBite(SoundBite soundBite)
        {
            if (!this.IsBusy)
            {
                throw new InvalidOperationException("PingLib-Loop: ERROR - Cannot add SoundBites when not initialized");
            }

            lock ( _soundBiteLock ) {
                _soundBite = new SoundBite(soundBite);
            }
        }
Пример #3
0
 /// <summary>
 /// Asynchronously plays a sound.
 ///  Waiting for this will not wait for when the Play has ended
 ///  but rather when the trigger for Output was given
 ///  There is currently no event available to detect end of Play
 /// </summary>
 /// <param name="soundBite">The SoundBite to play</param>
 public async Task PlayAsync(SoundBite soundBite)
 {
     if (!_canPlay)
     {
         return;        // Cannot
     }
     if (_playing)
     {
         return;       // no concurrent playing
     }
     await PlayAsyncLow(soundBite);
 }
Пример #4
0
        /// <summary>
        /// Add a sound to play
        /// </summary>
        /// <param name="soundBite">The SoundBite to play</param>
        public void AddSoundBite(SoundBite soundBite)
        {
            if (!this.IsBusy)
            {
                throw new InvalidOperationException("PingLib-Sound: ERROR Cannot add SoundBites when not initialized");
            }

            lock ( _soundBites ) {
                _soundBites.Enqueue(soundBite);
                // restart if needed
                if (_soundBites.Count == 1)
                {
                    _workerWaitHandle.Set( );
                }
            }
        }
Пример #5
0
 /// <summary>
 /// Clear the current Word queue
 /// </summary>
 public void ClearSoundBites( )
 {
     lock ( _soundBiteLock ) {
         _soundBite = new SoundBite( ); // Load a default (which is Silence in 1sec duration tones)
     }
 }
Пример #6
0
        // Async Speak output of a text
        private async Task PlayAsyncLow(SoundBite soundBite)
        {
            _playing = true; // locks additional calls for Speak until finished talking this bit

            if (!_canPlay || _audioGraph == null || _deviceOutputNode == null)
            {
                LOG.LogError($"PlayAsyncLow: Some items do not exist: cannot play..\n [{_audioGraph}] [{_deviceOutputNode}]");
                await EndOfSound( );

                return;
            }

            // don't reload if the sound is already in use
            if (soundBite.Melody != _soundInUse?.Melody)
            {
                // if a prev. Node exists, remove it
                if (_fileInputNode != null)
                {
                    _audioGraph.Stop( );

                    _fileInputNode.FileCompleted -= _fileInputNode_FileCompleted;
                    _fileInputNode.RemoveOutgoingConnection(_deviceOutputNode);
                    _fileInputNode.Dispose( );
                    _fileInputNode = null;
                }
                // set new sound
                _sound = _installedSounds.Where(x => x.Melody == soundBite.Melody).FirstOrDefault( );
                if (_sound == null)
                {
                    LOG.LogError($"PlayAsyncLow: Melody has no Audiofile: {soundBite.Melody} - cannot play");
                    await EndOfSound( );

                    return;
                }
                StorageFile file = await StorageFile.CreateStreamedFileAsync($"{_sound.Id}.{_sound.SType}", StreamedFileWriter, null);

                // create the InputNode
                var resultAF = await _audioGraph.CreateFileInputNodeAsync(file);

                if (resultAF.Status != AudioFileNodeCreationStatus.Success)
                {
                    LOG.LogError($"PlayAsyncLow: AudioFileNodeCreationStatus creation: {resultAF.Status}"
                                 + $"\nExtError: {resultAF.ExtendedError}");
                    await EndOfSound( );

                    return;
                }
                _fileInputNode = resultAF.FileInputNode;
                _fileInputNode.FileCompleted += _fileInputNode_FileCompleted;
                _fileInputNode.AddOutgoingConnection(_deviceOutputNode);

                _audioGraph.Start( );

                _soundInUse = _sound.AsCopy( );
            }

            // we capture problems through Exceptions here - the settings and restrictions seem not complete in the Docs
            try {
                // Play it
                // cannot start after prev end - so set it null and seek to start of file
                _fileInputNode.StartTime = null;
                _fileInputNode.EndTime   = null;      // cannot start after prev end - so set it null
                _fileInputNode.Seek(new TimeSpan(0)); // have to seek to Start, we cannot assign a StartTime before the current Position
                                                      // only now we can set any new start and end... (that is not in the documents...)
                _fileInputNode.StartTime           = TimeSpan.FromSeconds(soundBite.Tone * _soundInUse.ToneStep_sec);
                _fileInputNode.EndTime             = _fileInputNode.StartTime + TimeSpan.FromSeconds((soundBite.Duration < 0) ? _soundInUse.ToneDuration_sec : soundBite.Duration);
                _fileInputNode.OutgoingGain        = soundBite.Volume;
                _fileInputNode.LoopCount           = (int)soundBite.Loops; // counts down in the Completed Callback - track completeness there (not in docu...)
                _fileInputNode.PlaybackSpeedFactor = soundBite.SpeedFact;
                // Plays in the current Thread - cannot be waited for in the same thread
                _fileInputNode.Start( );
                //_audioGraph.Start( );
            }
            catch (Exception e) {
                LOG.LogError($"PlayAsyncLow: Sample Setup caused an Exception\n{e.Message}");
                await EndOfSound( );
            }
        }
Пример #7
0
        /// <summary>
        /// Synchronously plays soundBites
        /// Audio output is the default output device
        /// NOT YET IMPLEMENTED behaves the same as PlayAsync
        /// </summary>
        /// <param name="soundBite">The SoundBite to play</param>

        public void Play(SoundBite soundBite)
        {
            _player.AddSoundBite(soundBite);
            // TODO
        }
Пример #8
0
 /// <summary>
 /// Asynchronously plays soundBites
 /// Audio output is the default output device
 ///  This is not an awaitable method
 /// </summary>
 /// <param name="soundBite">The SoundBite to play (max 10sec supported)</param>
 public void PlayAsync(SoundBite soundBite)
 {
     _player.AddSoundBite(soundBite);
 }