//private long m_CircularBufferFlushTolerance; //private int m_CircularBufferPreviousBytesAvailableForWriting; private bool circularBufferRefreshThreadMethod() { //m_CircularBufferRefreshThreadIsAlive = true; //float previousFastPlayFactor = m_FastPlayFactor; //long predictedByteIncrement = -1; //int circularBufferTotalBytesPlayed = -1; //int previousCircularBufferPlayPosition = -1; Stopwatch transferBytesStopWatch = new Stopwatch(); transferBytesStopWatch.Stop(); int totalWriteSkips = 0; uint adjustedFastPlaySampleRate = (uint)Math.Round(m_CurrentAudioPCMFormat.SampleRate * m_FastPlayFactor); long pcmDataTotalPlayableFromStream = m_PlaybackEndPositionInCurrentAudioStream - m_PlaybackStartPositionInCurrentAudioStream; long pcmDataTotalPlayableFromStream_DurationMS = ( NotNormalPlayFactor() ? AudioLibPCMFormat.ConvertBytesToTime( pcmDataTotalPlayableFromStream, adjustedFastPlaySampleRate, m_CurrentAudioPCMFormat.BlockAlign #if DEBUG , true #endif ) : m_CurrentAudioPCMFormat.ConvertBytesToTime(pcmDataTotalPlayableFromStream) ) / AudioLibPCMFormat.TIME_UNIT; int slowLoop = 0; int sleepTime = REFRESH_INTERVAL_MS; //bool endOfAudioStream = false; while (true) { #if USE_SHARPDX DebugFix.Assert( m_CircularBuffer.Status == (int)BufferStatus.BufferLost || m_CircularBuffer.Status == (int)BufferStatus.Hardware || m_CircularBuffer.Status == (int)BufferStatus.Looping || m_CircularBuffer.Status == (int)BufferStatus.None || m_CircularBuffer.Status == (int)BufferStatus.Playing || m_CircularBuffer.Status == (int)BufferStatus.Software || m_CircularBuffer.Status == (int)BufferStatus.Terminated || m_CircularBuffer.Status == 5 //?! ); if (m_CircularBuffer.Status == (int)BufferStatus.BufferLost) { m_CircularBuffer.Restore(); } #else if (m_CircularBuffer.Status.BufferLost) { m_CircularBuffer.Restore(); } #endif #if USE_SHARPDX if (m_CircularBuffer.Status == (int)BufferStatus.Terminated || (m_CircularBuffer.Status != 5 && //?! m_CircularBuffer.Status != (int)BufferStatus.Playing && m_CircularBuffer.Status != (int)BufferStatus.Looping) ) { return(false); } #else if (m_CircularBuffer.Status.Terminated || (!m_CircularBuffer.Status.Playing && !m_CircularBuffer.Status.Looping) ) { return(false); } #endif Thread.Sleep(sleepTime); sleepTime = REFRESH_INTERVAL_MS; // reset after each loop // if (predictedByteIncrement < 0 // || true //m_FastPlayFactor != previousFastPlayFactor // ) // { // //previousFastPlayFactor = m_FastPlayFactor; // int fastPlaySamplesPerSecond = (int)Math.Round(m_CurrentAudioPCMFormat.SampleRate * m_FastPlayFactor); //#if DEBUG // DebugFix.Assert(m_CurrentAudioPCMFormat.SampleRate == m_CircularBuffer.Format.SamplesPerSecond); // if ( //#if USE_SOUNDTOUCH //!UseSoundTouch && //#endif //USE_SOUNDTOUCH //#if USE_SHARPDX // m_CircularBuffer.Capabilities.ControlFrequency //#else // m_CircularBuffer.Caps.ControlFrequency //#endif //) // { // DebugFix.Assert(m_CircularBuffer.Frequency == fastPlaySamplesPerSecond); // } //#endif //DEBUG // int byteRate = fastPlaySamplesPerSecond * m_CurrentAudioPCMFormat.BlockAlign; // (m_CurrentAudioPCMFormat.BitDepth / 8) * m_CurrentAudioPCMFormat.NumberOfChannels; // predictedByteIncrement = (long)(byteRate * (REFRESH_INTERVAL_MS + 15) / 1000.0); // predictedByteIncrement -= predictedByteIncrement % m_CurrentAudioPCMFormat.BlockAlign; // } #if USE_SHARPDX int circularBufferPlayPosition; int circularBufferWritePosition; m_CircularBuffer.GetCurrentPosition(out circularBufferPlayPosition, out circularBufferWritePosition); #else int circularBufferPlayPosition = m_CircularBuffer.PlayPosition; #endif int circularBufferLength = m_CircularBuffer. #if USE_SHARPDX Capabilities #else Caps #endif .BufferBytes ; //if (circularBufferTotalBytesPlayed < 0) //{ // circularBufferTotalBytesPlayed = circularBufferPlayPosition; //} //else //{ // if (circularBufferPlayPosition >= previousCircularBufferPlayPosition) // { // circularBufferTotalBytesPlayed += circularBufferPlayPosition - previousCircularBufferPlayPosition; // } // else // { // circularBufferTotalBytesPlayed += (circularBufferLength - previousCircularBufferPlayPosition) + circularBufferPlayPosition; // } //} //previousCircularBufferPlayPosition = circularBufferPlayPosition; // int totalBytesPlayed_AdjustedPlaybackRate = circularBufferTotalBytesPlayed; //#if USE_SOUNDTOUCH // if (UseSoundTouch && NotNormalPlayFactor()) // { // //m_CurrentAudioPCMFormat // totalBytesPlayed_AdjustedPlaybackRate = (int)Math.Round(totalBytesPlayed_AdjustedPlaybackRate * m_FastPlayFactor); // totalBytesPlayed_AdjustedPlaybackRate -= totalBytesPlayed_AdjustedPlaybackRate % m_CurrentAudioPCMFormat.BlockAlign; // } //#endif //USE_SOUNDTOUCH int circularBufferBytesAvailableForWriting = (circularBufferPlayPosition == m_CircularBufferWritePosition ? 0 : (circularBufferPlayPosition < m_CircularBufferWritePosition ? circularBufferPlayPosition + (circularBufferLength - m_CircularBufferWritePosition) : circularBufferPlayPosition - m_CircularBufferWritePosition)); //int circularBufferBytesAvailableForPlaying = circularBufferLength - circularBufferBytesAvailableForWriting; //realTimePlaybackPosition -= realTimePlaybackPosition % m_CurrentAudioPCMFormat.BlockAlign; //Console.WriteLine(String.Format("bytesAvailableForWriting: [{0} / {1}]", bytesAvailableForWriting, m_CircularBuffer.Caps.BufferBytes)); //Console.WriteLine("dataAvailableFromStream: " + dataAvailableFromStream); // int circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate = circularBufferBytesAvailableForPlaying; //#if USE_SOUNDTOUCH // if (UseSoundTouch && NotNormalPlayFactor()) // { // circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate = (int)Math.Round(circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate * m_FastPlayFactor); // circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate -= circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate % m_CurrentAudioPCMFormat.BlockAlign; // } //#endif //USE_SOUNDTOUCH long totalPlayedMS = m_PlaybackStopWatch.ElapsedMilliseconds; long totalPlayedBytes = ( NotNormalPlayFactor() ? AudioLibPCMFormat.ConvertTimeToBytes( totalPlayedMS * AudioLibPCMFormat.TIME_UNIT, (uint)adjustedFastPlaySampleRate, (ushort)m_CurrentAudioPCMFormat.BlockAlign #if DEBUG , true #endif ) : m_CurrentAudioPCMFormat.ConvertTimeToBytes(totalPlayedMS * AudioLibPCMFormat.TIME_UNIT) ); m_CurrentBytePosition = m_PlaybackStartPositionInCurrentAudioStream + totalPlayedBytes; //safeguard if (m_CurrentBytePosition < m_PlaybackStartPositionInCurrentAudioStream) { m_CurrentBytePosition = m_PlaybackStartPositionInCurrentAudioStream; } else if (m_CurrentBytePosition > m_PlaybackEndPositionInCurrentAudioStream) { m_CurrentBytePosition = m_PlaybackEndPositionInCurrentAudioStream; } //#if DEBUG // DebugFix.Assert(m_CurrentBytePosition >= m_PlaybackStartPositionInCurrentAudioStream); // DebugFix.Assert(m_CurrentBytePosition <= m_PlaybackEndPositionInCurrentAudioStream); //#endif // DEBUG //long remainingBytesToPlay = pcmDataTotalPlayableFromStream - totalBytesPlayed_AdjustedPlaybackRate; //long realTimePlaybackPosition = Math.Max(m_PlaybackStartPositionInCurrentAudioStream, // m_CurrentAudioStream.Position - Math.Min( // circularBufferBytesAvailableForPlaying_AdjustedPlaybackRate, remainingBytesToPlay)); //realTimePlaybackPosition = Math.Min(realTimePlaybackPosition, // m_PlaybackStartPositionInCurrentAudioStream + totalBytesPlayed_AdjustedPlaybackRate); //if (m_CurrentBytePosition == m_PlaybackStartPositionInCurrentAudioStream) //{ // //Console.WriteLine(string.Format("m_CurrentBytePosition ASSIGNED: realTimePlaybackPosition [{0}]", realTimePlaybackPosition)); // m_CurrentBytePosition += totalBytesPlayed_AdjustedPlaybackRate; //} ////else if (realTimePlaybackPosition < m_CurrentBytePosition) ////{ //// Console.WriteLine(string.Format("realTimePlaybackPosition [{0}] < m_CurrentBytePosition [{1}]", realTimePlaybackPosition, m_CurrentBytePosition)); //// m_CurrentBytePosition = Math.Min(m_PlaybackEndPositionInCurrentAudioStream, m_CurrentBytePosition + predictedByteIncrement); ////} ////else if (realTimePlaybackPosition > m_CurrentBytePosition + predictedByteIncrement) ////{ //// Console.WriteLine(string.Format("realTimePlaybackPosition [{0}] > m_CurrentBytePosition [{1}] + m_PredictedByteIncrement: [{2}] (diff: [{3}])", //// realTimePlaybackPosition, m_CurrentBytePosition, predictedByteIncrement, realTimePlaybackPosition - m_CurrentBytePosition)); //// m_CurrentBytePosition = Math.Min(m_PlaybackEndPositionInCurrentAudioStream, m_CurrentBytePosition + predictedByteIncrement); ////} //else //{ // //Console.WriteLine(string.Format("m_CurrentBytePosition OK: realTimePlaybackPosition [{0}]", realTimePlaybackPosition)); // m_CurrentBytePosition = m_PlaybackStartPositionInCurrentAudioStream + totalBytesPlayed_AdjustedPlaybackRate; //} PcmDataBufferAvailableHandler del = PcmDataBufferAvailable; if (del != null) { int min = Math.Min(m_PcmDataBufferLength, #if FETCH_PCM_FROM_CIRCULAR_BUFFER circularBufferBytesAvailableForPlaying #else (int)(m_PlaybackEndPositionInCurrentAudioStream - m_CurrentBytePosition) #endif // FETCH_PCM_FROM_CIRCULAR_BUFFER ); #if DEBUG DebugFix.Assert(min <= m_PcmDataBufferLength); DebugFix.Assert(min <= m_PcmDataBuffer.Length); #endif //DEBUG if (min >= m_CurrentAudioPCMFormat.BlockAlign) { #if FETCH_PCM_FROM_CIRCULAR_BUFFER #if USE_SHARPDX if (SharpDX_IntermediaryTransferBuffer != null) { Array.Copy(SharpDX_IntermediaryTransferBuffer, m_PcmDataBuffer, Math.Min(m_PcmDataBuffer.Length, SharpDX_IntermediaryTransferBuffer.Length)); } #else byte[] array = (byte[])m_CircularBuffer.Read( circularBufferPlayPosition, typeof(byte), LockFlag.None, min); //Array.Copy(array, m_PcmDataBuffer, min); Buffer.BlockCopy(array, 0, m_PcmDataBuffer, 0, min); #endif #else // !FETCH_PCM_FROM_CIRCULAR_BUFFER long pos = m_CurrentAudioStream.Position; m_CurrentAudioStream.Position = m_CurrentBytePosition; m_CurrentAudioStream.Read(m_PcmDataBuffer, 0, min); m_CurrentAudioStream.Position = pos; #endif m_PcmDataBufferAvailableEventArgs.PcmDataBuffer = m_PcmDataBuffer; m_PcmDataBufferAvailableEventArgs.PcmDataBufferLength = min; del(this, m_PcmDataBufferAvailableEventArgs); } } //var del_ = PcmDataBufferAvailable; //if (del_ != null //&& m_PcmDataBuffer.Length <= circularBufferBytesAvailableForPlaying) //{ //#if USE_SHARPDX //if (SharpDX_IntermediaryTransferBuffer != null) //{ //Array.Copy(SharpDX_IntermediaryTransferBuffer, m_PcmDataBuffer, Math.Min(m_PcmDataBuffer.Length, SharpDX_IntermediaryTransferBuffer.Length)); //m_PcmDataBufferAvailableEventArgs.PcmDataBuffer = m_PcmDataBuffer; //PcmDataBufferAvailable(this, m_PcmDataBufferAvailableEventArgs); //} //#else //Array array = m_CircularBuffer.Read(circularBufferPlayPosition, typeof(byte), LockFlag.None, m_PcmDataBuffer.Length); //Array.Copy(array, m_PcmDataBuffer, m_PcmDataBuffer.Length); //m_PcmDataBufferAvailableEventArgs.PcmDataBuffer = m_PcmDataBuffer; //del_(this, m_PcmDataBufferAvailableEventArgs); //#endif //} long pcmDataRemainingPlayableFromStream = m_PlaybackEndPositionInCurrentAudioStream - m_CurrentAudioStream.Position; //long pcmDataAlreadyReadFromStream = pcmDataTotalPlayableFromStream - pcmDataAvailableFromStream; if (circularBufferBytesAvailableForWriting <= 0) { if (pcmDataRemainingPlayableFromStream > 0) { //Console.WriteLine("circularBufferBytesAvailableForWriting <= 0, pcmDataAvailableFromStream > 0 ... continue..."); continue; } else { Console.WriteLine("circularBufferBytesAvailableForWriting <= 0, pcmDataAvailableFromStream <= 0 ... BREAK..."); break; } } //m_CircularBufferPreviousBytesAvailableForWriting = circularBufferBytesAvailableForWriting; // We have fed all of the available bytes from the audio stream to the circular secondary buffer. // Now we have to wait until the playback ends. if (pcmDataRemainingPlayableFromStream <= 0) { if ((m_PlaybackStopWatch.ElapsedMilliseconds + REFRESH_INTERVAL_MS) >= pcmDataTotalPlayableFromStream_DurationMS) { m_CircularBuffer.Stop(); return(true); } else { int newInterval = (int)Math.Round(REFRESH_INTERVAL_MS / 2.0); sleepTime = newInterval; continue; } //if (remainingBytesToPlay > predictedByteIncrement) //{ // Console.WriteLine(string.Format("remainingBytesToPlay [{0}] [{1}] [{2}] [{3}]", // pcmDataTotalPlayableFromStream, totalBytesPlayed_AdjustedPlaybackRate, remainingBytesToPlay, predictedByteIncrement)); // continue; //} //else //{ // m_CircularBuffer.Stop(); // //Console.WriteLine("Time to break, all bytes gone."); // //break; // return true; //} //if (m_CircularBufferFlushTolerance < 0) //{ // m_CircularBufferFlushTolerance = m_CurrentAudioPCMFormat.ConvertTimeToBytes(REFRESH_INTERVAL_MS*1.5); //} //Console.WriteLine(string.Format("pcmDataTotalPlayableFromStream [{0}]", pcmDataTotalPlayableFromStream)); //Console.WriteLine(String.Format("pcmDataAvailableFromStream <= 0 // circularBufferBytesAvailableForWriting [{0}], m_CircularBufferFlushTolerance [{1}], m_CircularBuffer.Caps.BufferBytes [{2}], m_CircularBufferPreviousBytesAvailableForWriting [{3}]", // circularBufferBytesAvailableForWriting, m_CircularBufferFlushTolerance, m_CircularBuffer.Caps.BufferBytes, m_CircularBufferPreviousBytesAvailableForWriting)); //if ((circularBufferBytesAvailableForWriting + m_CircularBufferFlushTolerance) >= m_CircularBuffer.Caps.BufferBytes // || m_CircularBufferPreviousBytesAvailableForWriting > circularBufferBytesAvailableForWriting) //{ // m_CircularBuffer.Stop(); // the earlier the better ? // Console.WriteLine("Forcing closing-up."); // circularBufferBytesAvailableForWriting = 0; // will enter the IF test below //} } else { // 2 thirds minimum of the circular buffer must be available, //otherwise skip until next sleep loop double ratio = 2 / 3.0; #if USE_SOUNDTOUCH if (UseSoundTouch && NotNormalPlayFactor()) { ratio /= m_FastPlayFactor; } #endif // USE_SOUNDTOUCH bool skip = circularBufferBytesAvailableForWriting < (int)Math.Round(circularBufferLength * ratio); if (false && skip) { totalWriteSkips++; } else { // int circularBufferBytesAvailableForWriting_AdjustedPlaybackRate = // circularBufferBytesAvailableForWriting; //#if USE_SOUNDTOUCH // if (UseSoundTouch && NotNormalPlayFactor()) // { // int bytesPerSample = (int)Math.Round(m_CurrentAudioPCMFormat.BitDepth / 8.0); // int bytesPerFrame = bytesPerSample * m_CurrentAudioPCMFormat.NumberOfChannels; // DebugFix.Assert(m_CurrentAudioPCMFormat.BlockAlign == bytesPerFrame); // circularBufferBytesAvailableForWriting_AdjustedPlaybackRate = // (int) // Math.Round(circularBufferBytesAvailableForWriting_AdjustedPlaybackRate // * m_FastPlayFactor // * m_CurrentAudioPCMFormat.NumberOfChannels); // circularBufferBytesAvailableForWriting_AdjustedPlaybackRate -= // circularBufferBytesAvailableForWriting_AdjustedPlaybackRate % // m_CurrentAudioPCMFormat.BlockAlign; // } //#endif //USE_SOUNDTOUCH //Console.WriteLine("totalWriteSkips: " + totalWriteSkips + " ms: " + totalWriteSkips*REFRESH_INTERVAL_MS); totalWriteSkips = 0; #if NET4 transferBytesStopWatch.Restart(); #else transferBytesStopWatch.Stop(); transferBytesStopWatch.Reset(); transferBytesStopWatch.Start(); #endif //NET4 int bytesWrittenToCirularBuffer = transferBytesFromWavStreamToCircularBuffer(circularBufferBytesAvailableForWriting); long timeMS = transferBytesStopWatch.ElapsedMilliseconds; transferBytesStopWatch.Stop(); //Console.WriteLine("transferBytesStopWatch: " + timeMS); sleepTime = Math.Max(10, REFRESH_INTERVAL_MS - (int)timeMS); #if USE_SOUNDTOUCH if (UseSoundTouch && NotNormalPlayFactor()) { if (timeMS >= REFRESH_INTERVAL_MS) { slowLoop++; } if (slowLoop > 2) { slowLoop = 0; Console.WriteLine("SOUNDTOUCH Enable SettingId.UseQuickseek"); m_SoundTouch.SetSetting(SettingId.UseQuickseek, 1); } } #endif //USE_SOUNDTOUCH //#if USE_SOUNDTOUCH // if (UseSoundTouch && NotNormalPlayFactor()) // { // int newInterval = (int)Math.Round(REFRESH_INTERVAL_MS / m_FastPlayFactor); // //sleepTime = newInterval; // } //#endif // USE_SOUNDTOUCH } } } // WHILE LOOP return(true); //CurrentState = State.Stopped; //AudioPlaybackFinishHandler delFinished = AudioPlaybackFinished; //if (delFinished != null && !mPreviewTimer.Enabled) // delFinished(this, new AudioPlaybackFinishEventArgs()); //if (!m_AllowBackToBackPlayback) //{ // AudioPlaybackFinishHandler delFinished = AudioPlaybackFinished; // if (delFinished != null && mEventsEnabled) // delFinished(this, new AudioPlaybackFinishEventArgs()); //} //else //{ // m_FinishedPlayingCurrentStream = true; //} }
/// <summary> /// Detects phrases of the asset for which stream is provided and returns timing list of detected phrases in local units /// </summary> /// <param name="assetStream"></param> /// <param name="audioPCMFormat"></param> /// <param name="threshold"></param> /// <param name="GapLength"></param> /// <param name="before"></param> /// <returns></returns> private static List <long> ApplyPhraseDetection(Stream assetStream, AudioLibPCMFormat audioPCMFormat, long threshold, double GapLength, double before) { CancelOperation = false; //m_AudioAsset = ManagedAsset.AudioMediaData; double assetTimeInMS = audioPCMFormat.ConvertBytesToTime(assetStream.Length) / AudioLibPCMFormat.TIME_UNIT; GapLength = audioPCMFormat.AdjustByteToBlockAlignFrameSize((long)GapLength); before = audioPCMFormat.AdjustByteToBlockAlignFrameSize((long)before); int Block = 0; // determine the Block size if (audioPCMFormat.SampleRate > 22500) { Block = 192; } else { Block = 96; } // count chunck of silence which trigger phrase detection long lCountSilGap = (long)(2 * GapLength) / Block; // multiplied by two because j counter is incremented by 2 long lSum = 0; List <double> detectedPhraseTimingList = new List <double>(); long lCheck = 0; // flags to indicate phrases and silence bool boolPhraseDetected = false; bool boolBeginPhraseDetected = false; double BlockTime = 25; // milliseconds double BeforePhraseInMS = audioPCMFormat.ConvertBytesToTime((long)before) / AudioLibPCMFormat.TIME_UNIT; //Console.WriteLine ("before , silgap " + BeforePhraseInMS+" , " + GapLength ) ; lCountSilGap = Convert.ToInt64((audioPCMFormat.ConvertBytesToTime((long)GapLength) / AudioLibPCMFormat.TIME_UNIT) / BlockTime); long Iterations = Convert.ToInt64(assetTimeInMS / BlockTime); long SampleCount = Convert.ToInt64(audioPCMFormat.SampleRate / (1000 / BlockTime)); double errorCompensatingCoefficient = GetErrorCompensatingConstant(SampleCount, audioPCMFormat); long SpeechBlockCount = 0; long lCurrentSum = 0; long lSumPrev = 0; BinaryReader br = new BinaryReader(assetStream); bool PhraseNominated = false; long SpeechChunkSize = 5; long Counter = 0; for (long j = 0; j < Iterations - 1; j++) { if (CancelOperation) { return(null); } // decodes audio chunck inside block //lCurrentSum = GetAverageSampleValue(br, SampleCount); lCurrentSum = GetAvragePeakValue(assetStream, SampleCount, audioPCMFormat); lSum = (lCurrentSum + lSumPrev) / 2; lSumPrev = lCurrentSum; // conditional triggering of phrase detection if (lSum < threshold) { lCheck++; SpeechBlockCount = 0; } else { if (j < lCountSilGap && boolBeginPhraseDetected == false) { boolBeginPhraseDetected = true; detectedPhraseTimingList.Add(Convert.ToInt64(0)); boolPhraseDetected = true; lCheck = 0; } // checks the length of silence if (lCheck > lCountSilGap) { PhraseNominated = true; lCheck = 0; } if (PhraseNominated) { SpeechBlockCount++; } if (SpeechBlockCount >= SpeechChunkSize && Counter >= 4) { //sets the detection flag boolPhraseDetected = true; // changing following time calculations to reduce concatination of rounding off errors //alPhrases.Add(((j - Counter) * BlockTime) - BeforePhraseInMS); //double phraseMarkTime = ObiCalculationFunctions.ConvertByteToTime (Convert.ToInt64(errorCompensatingCoefficient * (j - Counter)) * SampleCount * m_AudioAsset.PCMFormat.Data.BlockAlign, //(int) m_AudioAsset.PCMFormat.Data.SampleRate, //(int) m_AudioAsset.PCMFormat.Data.BlockAlign); long phraseMarkTime = audioPCMFormat.ConvertBytesToTime(Convert.ToInt64(errorCompensatingCoefficient * (j - Counter)) * SampleCount * audioPCMFormat.BlockAlign) / AudioLibPCMFormat.TIME_UNIT; //Console.WriteLine("mark time :" + phraseMarkTime); detectedPhraseTimingList.Add(phraseMarkTime - BeforePhraseInMS); SpeechBlockCount = 0; Counter = 0; PhraseNominated = false; } lCheck = 0; } if (PhraseNominated) { Counter++; } // end outer For } br.Close(); List <long> detectedPhraseTimingsInTimeUnits = new List <long>(); if (boolPhraseDetected == false) { return(null); } else { for (int i = 0; i < detectedPhraseTimingList.Count; i++) { detectedPhraseTimingsInTimeUnits.Add(Convert.ToInt64(detectedPhraseTimingList[i] * AudioLibPCMFormat.TIME_UNIT)); } } return(detectedPhraseTimingsInTimeUnits); }
// NewDetection // Detects the maximum size of noise level in a silent sample file public static long GetSilenceAmplitude(Stream assetStream, AudioLibPCMFormat audioPCMFormat) { CancelOperation = false; //m_AudioAsset = RefAsset.AudioMediaData; BinaryReader brRef = new BinaryReader(assetStream); // creates counter of size equal to clip size //long lSize = RefAsset.AudioMediaData.PCMFormat.Data.ConvertTimeToBytes(RefAsset.AudioMediaData.AudioDuration.AsLocalUnits); long lSize = audioPCMFormat.AdjustByteToBlockAlignFrameSize(assetStream.Length); // Block size of audio chunck which is least count of detection int Block; // determine the Block size if (audioPCMFormat.SampleRate > 22500) { Block = 192; } else { Block = 96; } //set reading position after the header long lLargest = 0; long lBlockSum; // adjust the lSize to avoid reading beyond file length //lSize = ((lSize / Block) * Block) - 4; // Experiment starts here double BlockTime = 25; double assetTimeInMS = audioPCMFormat.ConvertBytesToTime(assetStream.Length) / AudioLibPCMFormat.TIME_UNIT; //Console.WriteLine("assetTimeInMS " + assetTimeInMS); long Iterations = Convert.ToInt64(assetTimeInMS / BlockTime); long SampleCount = Convert.ToInt64((int)audioPCMFormat.SampleRate / (1000 / BlockTime)); long lCurrentSum = 0; long lSumPrev = 0; for (long j = 0; j < Iterations - 1; j++) { // BlockSum is function to retrieve average amplitude in Block //lCurrentSum = GetAverageSampleValue(brRef, SampleCount) ; lCurrentSum = GetAvragePeakValue(assetStream, SampleCount, audioPCMFormat); lBlockSum = Convert.ToInt64((lCurrentSum + lSumPrev) / 2); lSumPrev = lCurrentSum; if (lLargest < lBlockSum) { lLargest = lBlockSum; } if (CancelOperation) { break; } } long SilVal = Convert.ToInt64(lLargest); brRef.Close(); return(SilVal); }
public static long RemoveSilenceFromEnd(Stream assetStream, AudioLibPCMFormat audioPCMFormat, long threshold, double GapLength, double before) { GapLength = audioPCMFormat.ConvertTimeToBytes((long)GapLength); before = audioPCMFormat.ConvertTimeToBytes((long)before); CancelOperation = false; double assetTimeInMS = audioPCMFormat.ConvertBytesToTime(assetStream.Length) / AudioLibPCMFormat.TIME_UNIT; GapLength = audioPCMFormat.AdjustByteToBlockAlignFrameSize((long)GapLength); before = audioPCMFormat.AdjustByteToBlockAlignFrameSize((long)before); long lSum = 0; double detectedSilenceTime = 0; // flags to indicate phrases and silence bool boolPhraseDetected = false; double BlockTime = 25; // milliseconds long Iterations = Convert.ToInt64(assetTimeInMS / BlockTime); long SampleCount = Convert.ToInt64(audioPCMFormat.SampleRate / (1000 / BlockTime)); double errorCompensatingCoefficient = GetErrorCompensatingConstant(SampleCount, audioPCMFormat); long lCurrentSum = 0; long lSumPrev = 0; bool IsSilenceDetected = false; long phraseMarkTimeForDeletingSilence = 0; BinaryReader br = new BinaryReader(assetStream); for (long j = 0; j < Iterations - 1; j++) { if (CancelOperation) { return(0); } // decodes audio chunck inside block lCurrentSum = GetAvragePeakValue(assetStream, SampleCount, audioPCMFormat); lSum = (lCurrentSum + lSumPrev) / 2; lSumPrev = lCurrentSum; if (lSum < threshold) { if (!IsSilenceDetected) { phraseMarkTimeForDeletingSilence = audioPCMFormat.ConvertBytesToTime(Convert.ToInt64(errorCompensatingCoefficient * (j)) * SampleCount * audioPCMFormat.BlockAlign) / AudioLibPCMFormat.TIME_UNIT; IsSilenceDetected = true; } } else { IsSilenceDetected = false; phraseMarkTimeForDeletingSilence = 0; } } br.Close(); if (phraseMarkTimeForDeletingSilence != 0) { boolPhraseDetected = true; detectedSilenceTime = phraseMarkTimeForDeletingSilence + before; } long detectedPhraseTimingsInTimeUnits = 0; if (boolPhraseDetected == false) { return(0); } else { detectedPhraseTimingsInTimeUnits = Convert.ToInt64(detectedSilenceTime * AudioLibPCMFormat.TIME_UNIT); } return(detectedPhraseTimingsInTimeUnits); }