Example #1
0
        public static PlayItem DecodeToPlayItem(byte[] audioFileBytes)
        {
            var item = new PlayItem();

            // Audio file bytes into memory stream.
            using (var stream = new MemoryStream(audioFileBytes))
            {
                // Load existing XML and WAV data into PlayItem.
                using (var ms = new MemoryStream())
                {
                    // Loading stream into decoder.
                    using (var ad = new SharpDX.MediaFoundation.AudioDecoder(stream))
                    {
                        var samples    = ad.GetSamples();
                        var enumerator = samples.GetEnumerator();
                        while (enumerator.MoveNext())
                        {
                            var sample = enumerator.Current.ToArray();
                            ms.Write(sample, 0, sample.Length);
                        }
                        // Read WAV head.
                        item.WavHead = ad.WaveFormat;
                        // Read WAV data.
                        item.WavData  = ms.ToArray();
                        item.Duration = (int)ad.Duration.TotalMilliseconds;
                    }
                }
            }
            item.Status = JobStatusType.Synthesized;
            return(item);
        }
Example #2
0
        /// <summary>
        /// Load sound data.
        /// </summary>
        /// <param name="wavStream"></param>
        /// <returns>Returns duration.</returns>
        public decimal Load(Stream stream)
        {
            var ms         = new MemoryStream();
            var ad         = new SharpDX.MediaFoundation.AudioDecoder(stream);
            var samples    = ad.GetSamples();
            var enumerator = samples.GetEnumerator();

            while (enumerator.MoveNext())
            {
                var sample = enumerator.Current.ToArray();
                ms.Write(sample, 0, sample.Length);
            }
            var format = ad.WaveFormat;
            var bytes  = ms.ToArray();

            return(Load(bytes, format.SampleRate, format.BitsPerSample, format.Channels));
        }
Example #3
0
        /// <summary>
        /// Thread which will process all play items and convert XML to WAV bytes.
        /// </summary>
        /// <param name="status"></param>
        static void ProcessPlayItems(object status)
        {
            while (true)
            {
                PlayItem item = null;
                lock (threadIsRunningLock)
                {
                    lock (playlistLock)
                    {
                        // Get first incomplete item in the list.
                        JobStatusType[] validStates = { JobStatusType.Parsed, JobStatusType.Synthesized };
                        item = playlist.FirstOrDefault(x => validStates.Contains(x.Status));
                        // If nothing to do then...
                        if (item == null || playlist.Any(x => x.Status == JobStatusType.Error))
                        {
                            // Exit thread.
                            threadIsRunning = false;
                            return;
                        }
                    }
                }
                try
                {
                    // If XML is available.
                    if (item.Status == JobStatusType.Parsed)
                    {
                        item.Status = JobStatusType.Synthesizing;
                        var      encoding   = System.Text.Encoding.UTF8;
                        var      synthesize = true;
                        FileInfo xmlFi      = null;
                        FileInfo wavFi      = null;
                        if (SettingsManager.Options.CacheDataRead)
                        {
                            var dir = MainHelper.GetCreateCacheFolder();

                            // Look for generalized file first.
                            var uniqueName = item.GetUniqueFilePath(true);
                            // Get XML file path.
                            var xmlFile     = string.Format("{0}.xml", uniqueName);
                            var xmlFullPath = Path.Combine(dir.FullName, xmlFile);
                            xmlFi = new FileInfo(xmlFullPath);
                            // If generalized file do not exists then...
                            if (!xmlFi.Exists)
                            {
                                // Look for normal file.
                                uniqueName = item.GetUniqueFilePath(false);
                                // Get XML file path.
                                xmlFile     = string.Format("{0}.xml", uniqueName);
                                xmlFullPath = Path.Combine(dir.FullName, xmlFile);
                                xmlFi       = new FileInfo(xmlFullPath);
                            }
                            // Prefer MP3 audio file first (custom recorded file).
                            var wavFile     = string.Format("{0}.mp3", uniqueName);
                            var wavFullPath = Path.Combine(dir.FullName, wavFile);
                            wavFi = new FileInfo(wavFullPath);
                            // If wav do not exist or file is invalid.
                            if (!wavFi.Exists || wavFi.Length == 0)
                            {
                                // Get WAV file path.
                                wavFile     = string.Format("{0}.wav", uniqueName);
                                wavFullPath = Path.Combine(dir.FullName, wavFile);
                                wavFi       = new FileInfo(wavFullPath);
                            }
                            // If both files exists and Wav file is valid then...
                            if (xmlFi.Exists && wavFi.Exists && wavFi.Length > 0)
                            {
                                using (Stream stream = new FileStream(wavFi.FullName, FileMode.Open, FileAccess.Read))
                                {
                                    // Load existing XML and WAV data into PlayItem.
                                    var ms         = new MemoryStream();
                                    var ad         = new SharpDX.MediaFoundation.AudioDecoder(stream);
                                    var samples    = ad.GetSamples();
                                    var enumerator = samples.GetEnumerator();
                                    while (enumerator.MoveNext())
                                    {
                                        var sample = enumerator.Current.ToArray();
                                        ms.Write(sample, 0, sample.Length);
                                    }
                                    // Read WAV head.
                                    item.WavHead = ad.WaveFormat;
                                    // Read WAV data.
                                    item.WavData  = ms.ToArray();
                                    item.Duration = (int)ad.Duration.TotalMilliseconds;
                                }
                                // Load XML.
                                item.Xml = System.IO.File.ReadAllText(xmlFi.FullName);
                                // Make sure WAV data is not synthesized.
                                synthesize = false;
                            }
                        }
                        if (synthesize)
                        {
                            item.WavHead = new SharpDX.Multimedia.WaveFormat(
                                SettingsManager.Options.AudioSampleRate,
                                SettingsManager.Options.AudioBitsPerSample,
                                (int)SettingsManager.Options.AudioChannels);
                            // WavHead could change.
                            ConvertXmlToWav(item);
                        }
                        if (item.WavData != null)
                        {
                            var applyRate   = SettingsManager.Options.ModifyLocallyRate && _Rate != 0;
                            var applyPitch  = SettingsManager.Options.ModifyLocallyPitch && _Pitch != 0;
                            var applyVolume = SettingsManager.Options.ModifyLocallyVolume && item.Volume < 100;
                            if (applyRate || applyPitch)
                            {
                                var parameters = new SoundStretch.RunParameters();
                                parameters.TempoDelta = GetTempoDeltaFromRate(_Rate);
                                parameters.PitchDelta = (float)_Pitch;
                                parameters.Speech     = true;
                                var inStream = new MemoryStream();
                                AudioHelper.Write(item, inStream);
                                inStream.Position = 0;
                                var outStream = new MemoryStream();
                                SoundStretch.SoundTouchHelper.Process(inStream, outStream, parameters);
                                var outBytes = outStream.ToArray();
                                var pi       = DecodeToPlayItem(outBytes);
                                item.WavHead  = pi.WavHead;
                                item.WavData  = pi.WavData;
                                item.Duration = pi.Duration;
                                pi.Dispose();
                                inStream.Dispose();
                                outStream.Dispose();
                            }
                            if (applyVolume)
                            {
                                var inStream = new MemoryStream();
                                AudioHelper.Write(item, inStream);
                                inStream.Position = 0;
                                var vol       = (float)item.Volume / 100f;
                                var outStream = new MemoryStream();
                                AudioHelper.ChangeVolume(vol, inStream, outStream);
                                var outBytes = outStream.ToArray();
                                var pi       = DecodeToPlayItem(outBytes);
                                item.WavHead  = pi.WavHead;
                                item.WavData  = pi.WavData;
                                item.Duration = pi.Duration;
                                pi.Dispose();
                                inStream.Dispose();
                                outStream.Dispose();
                            }
                            if (SettingsManager.Options.CacheDataWrite || SettingsManager.Options.CacheAudioConvert)
                            {
                                // Create directory if not exists.
                                if (!xmlFi.Directory.Exists)
                                {
                                    xmlFi.Directory.Create();
                                }
                                if (!xmlFi.Exists)
                                {
                                    // Write XML.
                                    System.IO.File.WriteAllText(xmlFi.FullName, item.Xml, encoding);
                                }
                            }
                            // If data was synthesized i.e. was not loaded from the file then...
                            if (synthesize && SettingsManager.Options.CacheDataWrite)
                            {
                                AudioHelper.Write(item, wavFi);
                            }
                            // If must convert data to other formats.
                            if (SettingsManager.Options.CacheAudioConvert)
                            {
                                AudioHelper.Convert(item, wavFi);
                            }
                        }
                        item.Status = (item.WavHead == null || item.WavData == null)
                                                        ? item.Status = JobStatusType.Error
                                                        : item.Status = JobStatusType.Synthesized;
                    }
                    if (item.Status == JobStatusType.Synthesized)
                    {
                        item.Status = JobStatusType.Pitching;
                        ApplyPitch(item);
                        item.Status = JobStatusType.Pitched;
                    }
                }
                catch (Exception ex)
                {
                    OnEvent(Exception, ex);
                    item.Status = JobStatusType.Error;
                    // Exit thread.
                    threadIsRunning = false;
                    return;
                }
            }
        }