//These methods run on the main thread, they drain audio from the mic and send it across to the other thread for proper processing // // Update - Either discard mic samples (if no one is subscribed to mic data) or call DrainMicSamples // DrainMicSamples - Read as many samples as possible from the mic (using a set of pow2 sized buffers to get as // much as possible), passes samples to ConsumeMicSamples // ConsumeMicSamples - Take some number of samples from produced by DrainMicSamples and buffer them up, call SendFrame // every time some samples are added to the buffer // SendFrame - Read as many frames as possible from the buffer and send them to the other thread. Also poke the other thread // to tell it that it has work to do public void Update() { if (!_started) { _readHead = Microphone.GetPosition(_micName); _started = _readHead > 0; if (!_started) { return; } } if (_preprocessing.RequiresInput) { //Read samples from clip into mic sample buffer DrainMicSamples(); } else { //We're not interested in the audio from the mic, so skip the read head to the current mic position and drop all the audio _readHead = Microphone.GetPosition(_micName); _rawMicSamples.Reset(); _rawMicFrames.Reset(); _preprocessing.Reset(); if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } } }
protected void SendSamplesToSubscribers([NotNull] float[] buffer) { //Write processed audio to file (for diagnostic purposes) //ncrunch: no coverage start (Justification: don't want to have to write to disk in a test) if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordPreprocessorOutput) { if (_diagnosticOutputRecorder == null) { var filename = string.Format("Dissonance_Diagnostics/PreprocessorOutputAudio_{0}", DateTime.UtcNow.ToFileTime()); _diagnosticOutputRecorder = new AudioFileWriter(filename, OutputFormat); } _diagnosticOutputRecorder.WriteSamples(new ArraySegment <float>(buffer)); } //ncrunch: no coverage end //Send the audio to subscribers using (var unlocker = _micSubscriptions.Lock()) { var subs = unlocker.Value; for (var i = 0; i < subs.Count; i++) { try { subs[i].ReceiveMicrophoneData(new ArraySegment <float>(buffer), OutputFormat); } catch (Exception ex) { Log.Error("Microphone subscriber '{0}' threw: {1}", subs[i].GetType().Name, ex); } } } }
private void StopCapture() { if (!_subscribed) { throw Log.CreatePossibleBugException("Cannot unsubscribe encoder from mic: not subscribed", "8E0EAC83-BF44-4BE3-B132-BFE02AD1FADB"); } Log.Debug("Unsubscribing encoder from microphone"); _mic.Unsubscribe(this); _subscribed = false; _resetRequired = true; //Disposing the output writers is racy, because the audio thread is trying to write to them at the same time. //That's fine, because the writer have an internal SpinLock ensuring that doing this is safe if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } if (_preEncodeDiagnosticOutput != null) { _preEncodeDiagnosticOutput.Dispose(); _preEncodeDiagnosticOutput = null; } }
public virtual void Dispose() { _runThread = false; _threadEvent.Set(); if (_thread.IsStarted) { _thread.Join(); } //ncrunch: no coverage start if (_diagnosticOutputRecorder != null) { _diagnosticOutputRecorder.Dispose(); _diagnosticOutputRecorder = null; } //ncrunch: no coverage end using (var subscriptions = _micSubscriptions.Lock()) while (subscriptions.Value.Count > 0) { Unsubscribe(subscriptions.Value[0]); } using (var subscriptions = _vadSubscriptions.Lock()) while (subscriptions.Value.Count > 0) { Unsubscribe(subscriptions.Value[0]); } Log.Debug("Disposed pipeline"); }
public virtual void StopCapture() { Log.AssertAndThrowPossibleBug(_clip != null, "CDDAE69D-44DC-487F-9B69-4703B779400E", "Attempted to stop microphone capture, but it is already stopped"); //Stop diagnostic output if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } //Stop capture Microphone.End(_micName); _format = null; _clip = null; _readHead = 0; _started = false; _micName = null; //Clean the buffers _rawMicSamples.Reset(); _rawMicFrames.Reset(); //Stop watching for device changes AudioSettings.OnAudioConfigurationChanged -= OnAudioDeviceChanged; _audioDeviceChanged = false; }
//These methods run on the main thread, they drain audio from the mic and send it across to subscribers // // UpdateSubscribers - Either discard mic samples (if no one is subscribed to mic data) or call DrainMicSamples // DrainMicSamples - Read as many samples as possible from the mic (using a set of pow2 sized buffers to get as // much as possible), passes samples to ConsumeSamples // ConsumeMicSamples - Take some number of samples from produced by DrainMicSamples and buffer them up, call SendFrame // every time some samples are added to the buffer // SendFrame - Read as many frames as possible from the buffer and send them to the subscribers public bool UpdateSubscribers() { //Don't deliver any audio at all until microphone has initialised (i.e. delivered at least one sample) if (!_started) { _readHead = Microphone.GetPosition(_micName); _started = _readHead > 0; if (!_started) { return(false); } } // If the clip capacity is zero then something has gone horribly wrong! This can happen if the microphone hardware fails... // ...but we don't get an audio device reset event for some reason. Force the mic to reinitialize (hope it fixes the problem). if (_clip.samples == 0) { Log.Error("Unknown microphone capture error (zero length clip) - restarting mic"); return(true); } // If the audio device changes then we really don't know what state we're in any more (e.g. the mic could have just been unplugged). // Force the mic to reinitialize (setting us back to a known state). if (_audioDeviceChanged) { Log.Debug("Audio device changed - restarting mic"); return(true); } // If the microphone simply isn't recording at this point something has gone wrong, for example an external script has called Microphone.End // or something else has taken exclusive control of the mic. Force a reset and hope that fixes the issue. if (!Microphone.IsRecording(_micName)) { Log.Warn("Microphone stopped recording for an unknown reason (possibly due to an external script calling `Microphone.End`"); return(true); } if (_subscribers.Count > 0) { //There are subscribers - drain data from mic and pass it on to the subscribers DrainMicSamples(); } else { //No subscribers - discard the data in the mic input buffer _readHead = Microphone.GetPosition(_micName); _rawMicSamples.Reset(); _rawMicFrames.Reset(); if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } } return(false); }
public void Prepare(SessionContext context) { if (DebugSettings.Instance.EnablePlaybackDiagnostics && DebugSettings.Instance.RecordDecodedAudio) { var filename = string.Format("Dissonance_Diagnostics/Decoded_{0}_{1}_{2}", context.PlayerName, context.Id, DateTime.UtcNow.ToFileTime()); _diagnosticOutput = new AudioFileWriter(filename, _waveFormat); } }
public void Reset() { _buffer.Reset(); _decoder.Reset(); if (_diagnosticOutput != null) { _diagnosticOutput.Dispose(); _diagnosticOutput = null; } }
public FolderWriter(string FolderName, int FrameRate, IAudioProvider AudioProvider) { _folderPath = FolderName; SupportsAudio = AudioProvider != null; Directory.CreateDirectory(FolderName); File.WriteAllText(Path.Combine(FolderName, "FrameRate.txt"), FrameRate.ToString()); if (SupportsAudio) { _audioWriter = new AudioFileWriter(Path.Combine(FolderName, "audio.wav"), AudioProvider.WaveFormat); } }
public void Reset() { _buffer.Reset(); _decoder.Reset(); using (var l = _options.Lock()) l.Value = new PlaybackOptions(false, 1, ChannelPriority.Default); using (var l = _channels.Lock()) l.Value.Clear(); if (_diagnosticOutput != null) { _diagnosticOutput.Dispose(); _diagnosticOutput = null; } }
public void Dispose() { if (!_disposed) { _preprocessing.Dispose(); Microphone.End(_micName); if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } Log.Debug("Stopping audio capture thread"); } _disposed = true; }
/// <summary> /// Read as many frames as possible from the mic sample buffer and pass them to the encoding thread /// </summary> private void SendFrame() { //Drain as many frames as possible while (_rawMicSamples.Count > _rawMicFrames.FrameSize) { //Try to get a frame var segment = new ArraySegment <float>(_frame); var available = _rawMicFrames.Read(segment); if (!available) { break; } //Create diagnostic writer (if necessary) if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordMicrophoneRawAudio) { if (_microphoneDiagnosticOutput == null) { var filename = string.Format("Dissonance_Diagnostics/MicrophoneRawAudio_{0}", DateTime.UtcNow.ToFileTime()); _microphoneDiagnosticOutput = new AudioFileWriter(filename, _format); } } else if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } //Write out the diagnostic info if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.WriteSamples(segment); _microphoneDiagnosticOutput.Flush(); } //Send frame to subscribers for (var i = 0; i < _subscribers.Count; i++) { _subscribers[i].ReceiveMicrophoneData(segment, _format); } } }
/// <summary> /// Creates a new instance of <see cref="FFMpegMuxedWriter"/>. /// </summary> /// <param name="FilePath">Path for the output file.</param> /// <param name="FrameRate">Video Frame Rate.</param> public FFMpegMuxedWriter(string FilePath, int FrameRate, int VideoQuality, FFMpegVideoArgsProvider VideoArgsProvider, int AudioQuality, FFMpegAudioArgsProvider AudioArgsProvider, IAudioProvider AudioProvider) { if (AudioProvider == null) { throw new ArgumentNullException(nameof(AudioProvider), $"{nameof(AudioProvider)} can't be null. Use {nameof(FFMpegVideoWriter)} instead."); } if (!Directory.Exists(BaseDir)) { Directory.CreateDirectory(BaseDir); } var fileName = Path.GetFileName(FilePath); tempVideoPath = Path.Combine(BaseDir, fileName); tempAudioPath = Path.Combine(BaseDir, Path.ChangeExtension(fileName, ".wav")); _audioWriter = new AudioFileWriter(tempAudioPath, AudioProvider.WaveFormat); _videoWriter = new FFMpegVideoWriter(tempVideoPath, FrameRate, VideoQuality, VideoArgsProvider); _ffmpegArgs = $"-i {tempVideoPath} -vcodec copy -i {tempAudioPath} {AudioArgsProvider(AudioQuality)} \"{FilePath}\""; }
private void StartCapture() { if (_subscribed) { throw Log.CreatePossibleBugException("Cannot subscribe encoder to mic: already subscribed", "B1F845C2-3A9F-48F0-B9D2-4E5457CFDCB8"); } Log.Debug("Subscribing encoder to microphone"); if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordEncoderPipelineInputAudio) { var filename = string.Format("Dissonance_Diagnostics/EncoderPipelineInput_{0}", DateTime.UtcNow.ToFileTime()); _microphoneDiagnosticOutput = new AudioFileWriter(filename, _inputFormat); } if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordEncoderPipelineOutputAudio) { var filename = string.Format("Dissonance_Diagnostics/EncoderPipelineOutput_{0}", DateTime.UtcNow.ToFileTime()); _preEncodeDiagnosticOutput = new AudioFileWriter(filename, _output.WaveFormat); } _mic.Subscribe(this); _subscribed = true; }
/// <summary> /// Read as many frames as possible from the mic sample buffer and pass them to the encoding thread /// </summary> private void SendFrame() { while (_rawMicSamples.Count > _preprocessing.InputFrameSize) { //Get an empty buffer from the pool of buffers (sent back from the audio processing thread) var frameBuffer = _preprocessing.GetFrameBuffer(); //Read a complete frame _rawMicFrames.Read(new ArraySegment <float>(frameBuffer)); //Create diagnostic writer (if necessary) if (DebugSettings.Instance.EnableRecordingDiagnostics && DebugSettings.Instance.RecordMicrophoneRawAudio) { if (_microphoneDiagnosticOutput == null) { var filename = string.Format("Dissonance_Diagnostics/MicrophoneRawAudio_{0}", DateTime.UtcNow.ToFileTime()); _microphoneDiagnosticOutput = new AudioFileWriter(filename, _rawMicSamples.WaveFormat); } } else if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.Dispose(); _microphoneDiagnosticOutput = null; } //Write out the diagnostic info if (_microphoneDiagnosticOutput != null) { _microphoneDiagnosticOutput.WriteSamples(new ArraySegment <float>(frameBuffer)); _microphoneDiagnosticOutput.Flush(); } //Send the full buffer to the audio thread for processing (no copying, just pass the entire buffer across by ref) _preprocessing.Send(frameBuffer); } }
internal static bool Filter(SpeechSession session, float[] data, int channels, float[] temp, [CanBeNull] AudioFileWriter diagnosticOutput, out float arv, out int samplesRead, bool multiply) { //Read out data from source (exactly as much as we need for one channel) var samplesRequired = data.Length / channels; var complete = session.Read(new ArraySegment <float>(temp, 0, samplesRequired)); if (diagnosticOutput != null) { diagnosticOutput.WriteSamples(new ArraySegment <float>(temp, 0, samplesRequired)); } float accumulator = 0; //Step through samples, stretching them (i.e. play mono input in all output channels) var sampleIndex = 0; for (var i = 0; i < data.Length; i += channels) { //Get a single sample from the source data var sample = temp[sampleIndex++]; //Accumulate the sum of the audio signal accumulator += Mathf.Abs(sample); //Copy data into all channels for (var c = 0; c < channels; c++) { if (multiply) { data[i + c] *= sample; } else { data[i + c] = sample; } } } arv = accumulator / data.Length; samplesRead = samplesRequired; return(complete); }
public void OnAudioFilterRead(float[] data, int channels) { //If there is no session, clear filter and early exit var maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } _sessionLock.EnterUpgradeableReadLock(); try { //Check if there is no session again, this time protected by a lock maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } //Detect if the session has changed since the last call to this method, if so reset if (!maybeSession.Value.Context.Equals(_lastPlayedSessionContext)) { _lastPlayedSessionContext = maybeSession.Value.Context; ApplyReset(); } //Calculate the difference between where we should be and where we are (in samples) var session = maybeSession.Value; _desync.Update(IdealPlaybackPosition, PlaybackPosition); //If necessary skip samples to bring us back in sync int deltaDesync, deltaSamples; var complete = Skip(session, _desync.DesyncMilliseconds, out deltaSamples, out deltaDesync); Interlocked.Add(ref _totalSamplesRead, deltaSamples); _desync.Skip(deltaDesync); //If the session wasn't completed by the skip, keep playing if (!complete) { int samples; float arv; complete = Filter(session, data, channels, _temp, _diagnosticOutput, out arv, out samples, MultiplyBySource); _arv = arv; Interlocked.Add(ref _totalSamplesRead, samples); } //Clean up now that this session is complete if (complete) { Log.Debug("Finished playback of speech session. id={0}", session.Context.Id); //Clear the session _sessionLock.EnterWriteLock(); try { Session = null; } finally { _sessionLock.ExitWriteLock(); } //Reset the state ApplyReset(); //Discard the diagnostic recorder if necessary if (_diagnosticOutput != null) { _diagnosticOutput.Dispose(); _diagnosticOutput = null; } } } finally { _sessionLock.ExitUpgradeableReadLock(); } }
private void Record() { try { _stopWrite.Reset(); if (!String.IsNullOrEmpty(Micobject.recorder.trigger)) { string[] tid = Micobject.recorder.trigger.Split(','); switch (tid[0]) { case "1": VolumeLevel vl = MainForm.InstanceReference.GetVolumeLevel(Convert.ToInt32(tid[1])); if (vl != null && !vl.Recording) vl.RecordSwitch(true); break; case "2": CameraWindow c = MainForm.InstanceReference.GetCameraWindow(Convert.ToInt32(tid[1])); if (c != null && !c.Recording) c.RecordSwitch(true); break; } } var cw = CameraControl; // if (cw != null) { if (cw.AbortedAudio) { MainForm.LogErrorToFile(Micobject.name + ": paired recording aborted as the camera is already recording"); ForcedRecording = false; return; } } try { if (cw != null) { cw.ForcedRecording = ForcedRecording; cw.StartSaving(); _stopWrite.WaitOne(); } else { #region mp3writer DateTime date = DateTime.Now; string filename = String.Format("{0}-{1}-{2}_{3}-{4}-{5}", date.Year, Helper.ZeroPad(date.Month), Helper.ZeroPad(date.Day), Helper.ZeroPad(date.Hour), Helper.ZeroPad(date.Minute), Helper.ZeroPad(date.Second)); AudioFileName = Micobject.id + "_" + filename; string folder = Dir.Entry + "audio\\" + Micobject.directory + "\\"; if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); filename = folder + AudioFileName; _writer = new AudioFileWriter(); try { Program.FFMPEGMutex.WaitOne(); _writer.Open(filename + ".mp3", AudioCodec.MP3, AudioSource.RecordingFormat.BitsPerSample*AudioSource.RecordingFormat.SampleRate* AudioSource.RecordingFormat.Channels, AudioSource.RecordingFormat.SampleRate, AudioSource.RecordingFormat.Channels); } finally { try { Program.FFMPEGMutex.ReleaseMutex(); } catch (ObjectDisposedException) { //can happen on shutdown } } double maxlevel = 0; bool first = true; DateTime recordingStart = Helper.Now; try { while (!_stopWrite.WaitOne(5)) { Helper.FrameAction fa; while (Buffer.TryDequeue(out fa)) { if (first) { recordingStart = fa.TimeStamp; first = false; } if (fa.FrameType == Enums.FrameType.Audio) { unsafe { fixed (byte* p = fa.Content) { _writer.WriteAudio(p, fa.DataLength); } } float d = Levels.Max(); _soundData.Append(String.Format(CultureInfo.InvariantCulture, "{0:0.000}", d)); _soundData.Append(","); if (d > maxlevel) maxlevel = d; } fa.Nullify(); } } FilesFile ff = _filelist.FirstOrDefault(p => p.Filename.EndsWith(AudioFileName + ".mp3")); bool newfile = false; if (ff == null) { ff = new FilesFile(); newfile = true; } string[] fnpath = (filename + ".mp3").Split('\\'); string fn = fnpath[fnpath.Length - 1]; var fi = new FileInfo(filename + ".mp3"); var dSeconds = Convert.ToInt32((Helper.Now - recordingStart).TotalSeconds); ff.CreatedDateTicks = DateTime.Now.Ticks; ff.Filename = fnpath[fnpath.Length - 1]; ff.MaxAlarm = maxlevel; ff.SizeBytes = fi.Length; ff.DurationSeconds = dSeconds; ff.IsTimelapse = false; ff.IsMergeFile = false; ff.AlertData = Helper.GetMotionDataPoints(_soundData); _soundData.Clear(); ff.TriggerLevel = Micobject.detector.minsensitivity; ff.TriggerLevelMax = Micobject.detector.maxsensitivity; if (newfile) { lock (_lockobject) { _filelist.Insert(0, ff); } MainForm.MasterFileAdd(new FilePreview(fn, dSeconds, Micobject.name, DateTime.Now.Ticks, 1, Micobject.id, ff.MaxAlarm, false, false)); MainForm.NeedsMediaRefresh = Helper.Now; } } catch (Exception ex) { if (ErrorHandler != null) ErrorHandler(ex.Message); } if (_writer != null && _writer.IsOpen) { try { Program.FFMPEGMutex.WaitOne(); _writer.Dispose(); } catch (Exception ex) { if (ErrorHandler != null) ErrorHandler(ex.Message); } finally { try { Program.FFMPEGMutex.ReleaseMutex(); } catch (ObjectDisposedException) { //can happen on shutdown } } } _writer = null; #endregion } UpdateFloorplans(false); } catch (Exception ex) { if (ErrorHandler != null) ErrorHandler(ex.Message); } if (!String.IsNullOrEmpty(Micobject.recorder.trigger)) { string[] tid = Micobject.recorder.trigger.Split(','); switch (tid[0]) { case "1": VolumeLevel vl = MainForm.InstanceReference.GetVolumeLevel(Convert.ToInt32(tid[1])); if (vl != null) vl.RecordSwitch(false); break; case "2": CameraWindow c = MainForm.InstanceReference.GetCameraWindow(Convert.ToInt32(tid[1])); if (c != null) c.RecordSwitch(false); break; } } if (cw == null) { Micobject.newrecordingcount++; if (Notification != null) Notification(this, new NotificationType("NewRecording", Micobject.name, "")); } } catch (Exception ex) { MainForm.LogExceptionToFile(ex); } }
private void Record() { _stopWrite = false; DateTime recordingStart = DateTime.MinValue; if (!String.IsNullOrEmpty(Micobject.recorder.trigger) && TopLevelControl != null) { string[] tid = Micobject.recorder.trigger.Split(','); switch (tid[0]) { case "1": VolumeLevel vl = ((MainForm)TopLevelControl).GetVolumeLevel(Convert.ToInt32(tid[1])); if (vl != null) vl.RecordSwitch(true); break; case "2": CameraWindow cw = ((MainForm)TopLevelControl).GetCameraWindow(Convert.ToInt32(tid[1])); if (cw != null) cw.RecordSwitch(true); break; } } try { WriterBuffer = new QueueWithEvents<AudioAction>(); WriterBuffer.Changed += WriterBufferChanged; _pairedRecording = false; if (CameraControl!=null && CameraControl.Camobject.settings.active) { _pairedRecording = true; CameraControl.StartSaving(); CameraControl.ForcedRecording = ForcedRecording; while (!_stopWrite) { _newRecordingFrame.WaitOne(200); } } else { #region mp3writer DateTime date = DateTime.Now; string filename = String.Format("{0}-{1}-{2}_{3}-{4}-{5}", date.Year, Helper.ZeroPad(date.Month), Helper.ZeroPad(date.Day), Helper.ZeroPad(date.Hour), Helper.ZeroPad(date.Minute), Helper.ZeroPad(date.Second)); AudioFileName = Micobject.id + "_" + filename; filename = MainForm.Conf.MediaDirectory + "audio\\" + Micobject.directory + "\\"; filename += AudioFileName; Program.WriterMutex.WaitOne(); try { _writer = new AudioFileWriter(); _writer.Open(filename + ".mp3", AudioCodec.MP3, AudioSource.RecordingFormat.BitsPerSample * AudioSource.RecordingFormat.SampleRate * AudioSource.RecordingFormat.Channels, AudioSource.RecordingFormat.SampleRate, AudioSource.RecordingFormat.Channels); } catch (Exception ex) { Log.Error("",ex);//MainForm.LogExceptionToFile(ex); } finally { Program.WriterMutex.ReleaseMutex(); } double maxlevel = 0; foreach (AudioAction aa in AudioBuffer.OrderBy(p=>p.TimeStamp)) { if (recordingStart == DateTime.MinValue) { recordingStart = aa.TimeStamp; } unsafe { fixed (byte* p = aa.Decoded) { _writer.WriteAudio(p, aa.Decoded.Length); } } _soundData.Append(String.Format(CultureInfo.InvariantCulture, "{0:0.000}", aa.SoundLevel)); _soundData.Append(","); if (aa.SoundLevel > maxlevel) maxlevel = aa.SoundLevel; } AudioBuffer.Clear(); if (recordingStart == DateTime.MinValue) recordingStart = DateTime.Now; try { while (!_stopWrite) { while (WriterBuffer.Count > 0) { AudioAction b; lock (_obj) { b = WriterBuffer.Dequeue(); } unsafe { fixed (byte* p = b.Decoded) { _writer.WriteAudio(p, b.Decoded.Length); } } float d = Levels.Max(); _soundData.Append(String.Format(CultureInfo.InvariantCulture, "{0:0.000}", d)); _soundData.Append(","); if (d > maxlevel) maxlevel = d; } _newRecordingFrame.WaitOne(200); } FilesFile ff = FileList.FirstOrDefault(p => p.Filename.EndsWith(AudioFileName + ".mp3")); bool newfile = false; if (ff == null) { ff = new FilesFile(); newfile = true; } string[] fnpath = (filename + ".mp3").Split('\\'); string fn = fnpath[fnpath.Length - 1]; var fi = new FileInfo(filename + ".mp3"); var dSeconds = Convert.ToInt32((DateTime.Now - recordingStart).TotalSeconds); ff.CreatedDateTicks = DateTime.Now.Ticks; ff.Filename = fnpath[fnpath.Length - 1]; ff.MaxAlarm = maxlevel; ff.SizeBytes = fi.Length; ff.DurationSeconds = dSeconds; ff.IsTimelapse = false; ff.AlertData = Helper.GetMotionDataPoints(_soundData); _soundData.Clear(); ff.TriggerLevel = Micobject.detector.sensitivity; if (newfile) { FileList.Insert(0, ff); if (MainForm.MasterFileList.Count(p => p.Filename.EndsWith(fn)) == 0) { MainForm.MasterFileList.Add(new FilePreview(fn, dSeconds, Micobject.name, DateTime.Now.Ticks, 1,Micobject.id, ff.MaxAlarm)); } } } catch (Exception ex) { Log.Error("",ex);//MainForm.LogExceptionToFile(ex); } Program.WriterMutex.WaitOne(); try { _writer.Close(); _writer.Dispose(); } catch (Exception ex) { Log.Error("",ex);//MainForm.LogExceptionToFile(ex); } finally { Program.WriterMutex.ReleaseMutex(); } _writer = null; #endregion } _stopWrite = false; WriterBuffer = null; _recordingTime = 0; UpdateFloorplans(false); } catch (Exception ex) { Log.Error("",ex);//MainForm.LogExceptionToFile(ex); } if (!String.IsNullOrEmpty(Micobject.recorder.trigger) && TopLevelControl != null) { string[] tid = Micobject.recorder.trigger.Split(','); switch (tid[0]) { case "1": VolumeLevel vl = ((MainForm)TopLevelControl).GetVolumeLevel(Convert.ToInt32(tid[1])); if (vl != null) vl.RecordSwitch(false); break; case "2": CameraWindow cw = ((MainForm)TopLevelControl).GetCameraWindow(Convert.ToInt32(tid[1])); if (cw != null) cw.RecordSwitch(false); break; } } if (!_pairedRecording) { Micobject.newrecordingcount++; if (Notification != null) Notification(this, new NotificationType("NewRecording", Micobject.name, "")); } }
internal static bool Filter(SpeechSession session, [NotNull] float[] output, int channels, [NotNull] float[] temp, [CanBeNull] AudioFileWriter diagnosticOutput, out float arv) { //Read out data from source (exactly as much as we need for one channel) var samplesRequired = output.Length / channels; var complete = session.Read(new ArraySegment <float>(temp, 0, samplesRequired)); //Write the audio we're about to play to the diagnostics writer (on disk) if (diagnosticOutput != null) { diagnosticOutput.WriteSamples(new ArraySegment <float>(temp, 0, samplesRequired)); } //Step through samples, stretching them (i.e. play mono input in all output channels) float accumulator = 0; var sampleIndex = 0; for (var i = 0; i < output.Length; i += channels) { //Get a single sample from the source data var sample = temp[sampleIndex++]; //Accumulate the sum of the audio signal accumulator += Mathf.Abs(sample); //Copy data into all channels for (var c = 0; c < channels; c++) { output[i + c] *= sample; } } arv = accumulator / output.Length; return(complete); }
public void OnAudioFilterRead([NotNull] float[] data, int channels) { //If there is no session, clear filter and early exit var maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } _sessionLock.EnterUpgradeableReadLock(); try { //Check if there is no session again, this time protected by a lock maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } //Detect if the session has changed since the last call to this method, if so reset var session = maybeSession.Value; if (!session.Context.Equals(_lastPlayedSessionContext)) { _lastPlayedSessionContext = maybeSession.Value.Context; ApplyReset(); } // Read data from pipeline float arv; var complete = Filter(session, data, channels, _temp, _diagnosticOutput, out arv); _arv = arv; //Clean up now that this session is complete if (complete) { Log.Debug("Finished playback of speech session. id={0}. player={1}", session.Context.Id, session.Context.PlayerName); //Clear the session _sessionLock.EnterWriteLock(); try { Session = null; } finally { _sessionLock.ExitWriteLock(); } //Reset the state ApplyReset(); //Discard the diagnostic recorder if necessary if (_diagnosticOutput != null) { _diagnosticOutput.Dispose(); _diagnosticOutput = null; } } } finally { _sessionLock.ExitUpgradeableReadLock(); } }