public static bool ExportSample(SampleGeneratingArgs sampleGeneratingArgs, string name,
                                        string exportFolder, Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null,
                                        SampleExportFormat format = SampleExportFormat.Default)
        {
            // Export as midi file with single note
            if (format == SampleExportFormat.MidiChords)
            {
                MidiExporter.SaveToFile(Path.Combine(exportFolder, name + ".mid"), new[] { sampleGeneratingArgs });
                return(true);
            }

            if (sampleGeneratingArgs.CanCopyPaste && format == SampleExportFormat.Default)
            {
                var dest = Path.Combine(exportFolder, name + sampleGeneratingArgs.GetExtension());
                return(CopySample(sampleGeneratingArgs.Path, dest));
            }

            SampleSoundGenerator sampleSoundGenerator;

            if (loadedSamples != null)
            {
                if (SampleImporter.ValidateSampleArgs(sampleGeneratingArgs, loadedSamples))
                {
                    sampleSoundGenerator = loadedSamples[sampleGeneratingArgs];
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                try {
                    sampleSoundGenerator = SampleImporter.ImportSample(sampleGeneratingArgs);
                } catch (Exception ex) {
                    Console.WriteLine($@"{ex.Message} while importing sample {sampleGeneratingArgs}.");
                    return(false);
                }
            }

            var sourceWaveEncoding = sampleSoundGenerator.Wave.WaveFormat.Encoding;

            // Either if it is the blank sample or the source file is literally what the user wants to be exported
            if (sampleSoundGenerator.BlankSample && sampleGeneratingArgs.GetExtension() == ".wav" ||
                sampleGeneratingArgs.CanCopyPaste && IsCopyCompatible(sampleGeneratingArgs, sourceWaveEncoding, format))
            {
                var dest = Path.Combine(exportFolder, name + sampleGeneratingArgs.GetExtension());
                return(CopySample(sampleGeneratingArgs.Path, dest));
            }

            var sampleProvider = sampleSoundGenerator.GetSampleProvider();

            if ((format == SampleExportFormat.WavePcm || format == SampleExportFormat.OggVorbis) && sourceWaveEncoding == WaveFormatEncoding.IeeeFloat)
            {
                // When the source is IEEE float and the export format is PCM or Vorbis, then clipping is possible, so we add a limiter
                sampleProvider = new SoftLimiter(sampleProvider);
            }

            switch (format)
            {
            case SampleExportFormat.WaveIeeeFloat:
                CreateWaveFile(Path.Combine(exportFolder, name + ".wav"), sampleProvider.ToWaveProvider());
                break;

            case SampleExportFormat.WavePcm:
                CreateWaveFile(Path.Combine(exportFolder, name + ".wav"), sampleProvider.ToWaveProvider16());
                break;

            case SampleExportFormat.OggVorbis:
                var resampled = new WdlResamplingSampleProvider(sampleProvider,
                                                                VorbisFileWriter.GetSupportedSampleRate(sampleProvider.WaveFormat.SampleRate));
                VorbisFileWriter.CreateVorbisFile(Path.Combine(exportFolder, name + ".ogg"), resampled.ToWaveProvider());
                break;

            default:
                switch (sourceWaveEncoding)
                {
                case WaveFormatEncoding.IeeeFloat:
                    CreateWaveFile(Path.Combine(exportFolder, name + ".wav"), sampleProvider.ToWaveProvider());
                    break;

                case WaveFormatEncoding.Pcm:
                    CreateWaveFile(Path.Combine(exportFolder, name + ".wav"), sampleProvider.ToWaveProvider16());
                    break;

                default:
                    CreateWaveFile(Path.Combine(exportFolder, name + ".wav"), sampleProvider.ToWaveProvider());
                    break;
                }

                break;
            }

            return(true);
        }
示例#2
0
        private void PlayThread()
        {
            ResamplerDmoStream          resamplerDmoStream = null;
            IWaveProvider               playbackProvider   = sourceProvider;
            Exception                   exception          = null;
            WdlResamplingSampleProvider resamplerWdlStream = null;

            try
            {
                if (dmoResamplerNeeded)
                {
                    if (!windowsN)
                    {
                        resamplerDmoStream = new ResamplerDmoStream(sourceProvider, outputFormat);
                        playbackProvider   = resamplerDmoStream;
                    }
                    else
                    {
                        resamplerWdlStream = new WdlResamplingSampleProvider(sourceProvider.ToSampleProvider(), outputFormat.SampleRate);
                        playbackProvider   = resamplerWdlStream.ToWaveProvider();
                    }
                }

                // fill a whole buffer
                bufferFrameCount = audioClient.BufferSize;
                bytesPerFrame    = outputFormat.Channels * outputFormat.BitsPerSample / 8;
                readBuffer       = new byte[bufferFrameCount * bytesPerFrame];
                FillBuffer(playbackProvider, bufferFrameCount);

                // Create WaitHandle for sync
                var waitHandles = new WaitHandle[] { frameEventWaitHandle };

                audioClient.Start();

                while (playbackState != PlaybackState.Stopped)
                {
                    // If using Event Sync, Wait for notification from AudioClient or Sleep half latency
                    int indexHandle = 0;
                    if (isUsingEventSync)
                    {
                        indexHandle = WaitHandle.WaitAny(waitHandles, 3 * latencyMilliseconds, false);
                    }
                    else
                    {
                        Thread.Sleep(latencyMilliseconds / 2);
                    }

                    // If still playing and notification is ok
                    if (playbackState == PlaybackState.Playing && indexHandle != WaitHandle.WaitTimeout)
                    {
                        // See how much buffer space is available.
                        int numFramesPadding;
                        if (isUsingEventSync)
                        {
                            // In exclusive mode, always ask the max = bufferFrameCount = audioClient.BufferSize
                            numFramesPadding = (shareMode == AudioClientShareMode.Shared) ? audioClient.CurrentPadding : 0;
                        }
                        else
                        {
                            numFramesPadding = audioClient.CurrentPadding;
                        }
                        int numFramesAvailable = bufferFrameCount - numFramesPadding;
                        if (numFramesAvailable > 10) // see https://naudio.codeplex.com/workitem/16363
                        {
                            FillBuffer(playbackProvider, numFramesAvailable);
                        }
                    }
                }
                Thread.Sleep(latencyMilliseconds / 2);
                audioClient.Stop();
                if (playbackState == PlaybackState.Stopped)
                {
                    audioClient.Reset();
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
                if (resamplerDmoStream != null)
                {
                    resamplerDmoStream.Dispose();
                }
                RaisePlaybackStopped(exception);
            }
        }