示例#1
0
        private IWaveSource GetSoundSource(Stream stream)
        {
            var magic = new byte[8];

            stream.Read(magic, 0, 8);
            stream.Position = 0;

            if (VisualC.CompareMemory(magic, _mp3Magic, 3) == 0 ||
                VisualC.CompareMemory(magic, _mp3Magic2, 2) == 0)
            {
                return(new DmoMp3Decoder(stream));
            }
            if (VisualC.CompareMemory(magic, _oggMagic, 4) == 0)
            {
                stream.Position = 0x1C;
                stream.Read(magic, 0, 8);
                stream.Position = 0;

                if (VisualC.CompareMemory(magic, _opusMagic, 8) == 0)
                {
                    throw new NotSupportedException("Ogg Opus is not currently supported.");
                }

                var decoder   = new VorbisDecoder(stream);
                var converter = new SampleToPcm16(decoder);
                return(converter);
            }
            if (VisualC.CompareMemory(magic, _flacMagic, 4) == 0)
            {
                return(new FlacFile(stream, FlacPreScanMode.Sync));
            }
            if (VisualC.CompareMemory(magic, _riffMagic, 4) == 0)
            {
                stream.Position = 8;
                stream.Read(magic, 0, 7);
                if (VisualC.CompareMemory(magic, _waveMagic, 7) == 0)
                {
                    return(new MediaFoundationDecoder(stream));
                }
                stream.Position = 0;
            }
            if (VisualC.CompareMemory(magic, _m4aMagic, 7) == 0)
            {
                return(new MediaFoundationDecoder(stream));
            }

            throw new FormatException("The stream is an unsupported format.");
        }
示例#2
0
        //***********************************************************************************************************************************************************************************************************

        #region Control recorder (start, stop, pause, resume)

        /// <summary>
        /// Start a new record
        /// </summary>
        public void StartRecord()
        {
            try
            {
                if (RecordState == RecordStates.RECORDING)
                {
                    return;
                }

                if (TrackInfo == null)
                {
                    _logHandle.Report(new LogEventWarning("Record not started, because no track info exists."));
                    return;
                }
                CreateFilePath();
                if (RecorderRecSettings.FileExistMode == RecorderFileExistModes.SKIP && (System.IO.File.Exists(FileStrWAV) || System.IO.File.Exists(FileStrMP3)))
                {
                    _logHandle.Report(new LogEventWarning("Record (\"" + TrackInfo?.TrackName + "\") not started, because FileExistMode == SKIP and file already exists."));
                    return;
                }

                if (!Directory.Exists(RecorderRecSettings.BasePath))
                {
                    _logHandle.Report(new LogEventWarning("Record (\"" + TrackInfo?.TrackName + "\") not started, because RecordPath is invalid."));
                    return;
                }

                if (WasapiOut.IsSupportedOnCurrentPlatform)
                {
                    _silenceOut = new WasapiOut();
                }
                else
                {
                    _silenceOut = new DirectSoundOut();
                }
                _silenceOut.Initialize(new SilenceGenerator());
                _silenceOut.Play();         //Play silence because otherwise silent parts aren't recorded

                _capture = new WasapiLoopbackCapture();

                MMDeviceEnumerator devEnumerator = new MMDeviceEnumerator();
                MMDeviceCollection mMDevices     = devEnumerator.EnumAudioEndpoints(DataFlow.All, DeviceState.All);

                MMDevice dev;
                if (RecorderRecSettings.RecorderDeviceName.ToLower().Contains("default"))
                {
                    dev = devEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
                }
                else
                {
                    dev = mMDevices.Where(d => d.DeviceState == DeviceState.Active && d.FriendlyName == RecorderRecSettings.RecorderDeviceName)?.First();
                }

                if (dev == null)
                {
                    _logHandle.Report(new LogEventError("Record (\"" + TrackInfo?.TrackName + "\") not started, because device \"" + RecorderRecSettings.RecorderDeviceName + "\" wasn't found." + (RecorderRecSettings.RecorderDeviceName.Contains("CABLE Input") ? " Make sure that \"VB Cable\" is installed correctly." : "")));
                    return;
                }

                _capture.Device = dev;
                _capture.Initialize();      // Important!!! First set the capture device, then call Initialize(); otherwise audio is captured from the previous device

                SoundInSource soundInSource    = new SoundInSource(_capture);
                SampleToPcm16 soundInSourcePCM = new SampleToPcm16(soundInSource.ToSampleSource());     //Used to convert _capture to Pcm16 format

                Directory.CreateDirectory(Path.GetDirectoryName(FileStrWAV));
                _wavWriterFormat        = new WaveFormat(_capture.WaveFormat.SampleRate, soundInSourcePCM.WaveFormat.BitsPerSample, _capture.WaveFormat.Channels, AudioEncoding.Pcm, _capture.WaveFormat.ExtraSize); //WAV file must be 16-bit PCM file for normalizing with normalize.exe
                _wavWriter              = new WaveWriter(FileStrWAV, _wavWriterFormat);
                _wavWriterPositionBytes = 0;

                soundInSource.DataAvailable += (s, capData) =>
                {
                    if (RecordState == RecordStates.RECORDING)              //Only record when RecordState is RECORDING
                    {
                        byte[] buffer = new byte[soundInSourcePCM.WaveFormat.BytesPerSecond / 2];
                        int    read;

                        while ((read = soundInSourcePCM.Read(buffer, 0, buffer.Length)) > 0) //keep reading as long as we still get some data
                        {
                            _wavWriter.Write(buffer, 0, read);                               //write the read data to a file
                            _wavWriterPositionBytes += read;
                        }
                    }
                };

                _capture.Start();

                RecordState = RecordStates.RECORDING;
                _logHandle.Report(new LogEventInfo("Record (\"" + TrackInfo?.TrackName + "\") started."));
                WasRecordPaused = false;
            }
            catch (Exception ex)
            {
                _logHandle.Report(new LogEventError("Error while starting record: " + ex.Message));
            }
        }