private void onCircularBufferTimerTick(object sender, EventArgs e) { //#if DEBUG // Console.WriteLine("TICK"); //#endif if (m_PreviousTotalRecordedBytes == m_TotalRecordedBytes && // Skipped notifications? CurrentState == State.Recording) { m_DO_LOG_CircularBufferNotificationTimerMessage = true; String msg = "DO_LOG_CircularBufferNotificationTimerMessage:: onCircularBufferTimerTick EVENT SET (skipped notifications?) " + m_PreviousTotalRecordedBytes + " / " + m_TotalRecordedBytes; #if DEBUG Console.WriteLine(msg); System.Media.SystemSounds.Asterisk.Play(); #endif CircularBufferNotificationTimerMessageHandler del = CircularBufferNotificationTimerMessage; if (del != null) { del(this, new CircularBufferNotificationTimerMessageEventArgs(msg)); } // See relevant legacy old code diffs: //http://daisy-trac.cvsdude.com/urakawa-sdk/changeset?reponame=&new=1411%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs&old=1405%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs //http://daisy-trac.cvsdude.com/urakawa-sdk/changeset?reponame=&new=1490%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs&old=1486%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs //http://daisy-trac.cvsdude.com/urakawa-sdk/changeset?reponame=&new=1494%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs&old=1491%40trunk%2Fcsharp%2Faudio%2FAudioLib%2FAudioRecorder.cs //m_CircularBufferNotificationEvent.WaitOne(1); m_CircularBufferNotificationEvent.Set(); } else { m_DO_LOG_CircularBufferNotificationTimerMessage = false; } m_PreviousTotalRecordedBytes = m_TotalRecordedBytes; }
//private int m_circularBufferCapturePosition = -1; #endif private int circularBufferTransferData( #if !FORCE_SINGLE_NOTIFICATION_EVENT int eventIndex, bool catchingUp, #endif bool lastFlush ) { #if !FORCE_SINGLE_NOTIFICATION_EVENT #if SIMULATE_BUFFER_NOTIFICATION_SKIP Console.WriteLine(eventIndex); #endif if (!catchingUp) { #if SIMULATE_BUFFER_NOTIFICATION_SKIP // NOTIFICATIONS = 16, each REFRESH_INTERVAL_MS = 75 bool beginning = eventIndex == 0 || eventIndex == 1 || eventIndex == 2; bool end = eventIndex == 13 || eventIndex == 14 || eventIndex == 15; bool middle = eventIndex == 6 || eventIndex == 7 || eventIndex == 8; bool middleTwo = eventIndex == 3 || eventIndex == 4 || eventIndex == 5 || eventIndex == 9 || eventIndex == 10 || eventIndex == 11; //if (beginning) //if (end) //if (beginning || end) //if (beginning || middle) //if (middle || end) if (beginning || middle || end) //if (middle) //if (middleTwo) { Console.WriteLine("SKIPPED."); return(0); } #endif if ((m_previousEventIndex == -1 || m_previousEventIndex >= 0) && eventIndex >= 0) { int nextEventIndex = m_previousEventIndex + 1; if (nextEventIndex >= NOTIFICATIONS) { nextEventIndex = 0; } int toCatchUp = 0; if (eventIndex == nextEventIndex) { // OK } else if (eventIndex > nextEventIndex) { // ahead, but not looped back in circular buffer toCatchUp = eventIndex - nextEventIndex; } else if (eventIndex < nextEventIndex) { // ahead, but looped back in circular buffer toCatchUp = (NOTIFICATIONS - nextEventIndex) + eventIndex; } if (toCatchUp > 0) { #if SIMULATE_BUFFER_NOTIFICATION_SKIP Console.WriteLine("TO CATCHUP: {0}", toCatchUp); #endif for (int i = 0; i < toCatchUp; i++) { #if SIMULATE_BUFFER_NOTIFICATION_SKIP Console.WriteLine("Audio recording event catch-up {0}, {1} => {2}", eventIndex, m_previousEventIndex, nextEventIndex); #endif circularBufferTransferData(nextEventIndex, true, lastFlush); nextEventIndex++; if (nextEventIndex >= NOTIFICATIONS) { nextEventIndex = 0; } } //DebugFix.Assert(m_previousEventIndex == (eventIndex-1)); } } } m_previousEventIndex = eventIndex; #endif #if USE_SHARPDX int circularBufferCapturePosition = m_CircularBuffer.CurrentCapturePosition; //int readPosition = m_CircularBuffer.CurrentRealPosition; #else int circularBufferCapturePosition; int readPosition; // UNUSED m_CircularBuffer.GetCurrentPosition(out circularBufferCapturePosition, out readPosition); #endif //#if !FORCE_SINGLE_NOTIFICATION_EVENT // if (catchingUp) // { // circularBufferCapturePosition = m_circularBufferCapturePosition; // } // else // { // m_circularBufferCapturePosition = circularBufferCapturePosition; // } //#endif int circularBufferBytes = m_CircularBuffer. #if USE_SHARPDX Capabilities #else Caps #endif .BufferBytes ; int notifyChunk = circularBufferBytes / NOTIFICATIONS; int circularBufferBytesAvailableForReading = (circularBufferCapturePosition == m_CircularBufferReadPositon ? 0 : (circularBufferCapturePosition < m_CircularBufferReadPositon ? circularBufferCapturePosition + (circularBufferBytes - m_CircularBufferReadPositon) : circularBufferCapturePosition - m_CircularBufferReadPositon)); if (lastFlush) { #if !FORCE_SINGLE_NOTIFICATION_EVENT DebugFix.Assert(eventIndex == -1); #endif //circularBufferBytesAvailableForReading -= (circularBufferBytesAvailableForReading % notifyChunk); #if DEBUG Console.WriteLine("m_CircularBufferReadPositon: " + m_CircularBufferReadPositon); Console.WriteLine("circularBufferBytesAvailableForReading; " + circularBufferBytesAvailableForReading); #endif } else { #if !FORCE_SINGLE_NOTIFICATION_EVENT DebugFix.Assert(eventIndex >= 0); circularBufferBytesAvailableForReading = notifyChunk; #endif } if (circularBufferBytesAvailableForReading <= 0) { //Console.WriteLine(string.Format("circularBufferTransferData: no more bytes to fetch {0}", circularBufferBytesAvailableForReading)); return(circularBufferBytesAvailableForReading); } DebugFix.Assert(circularBufferBytesAvailableForReading <= circularBufferBytes); if (circularBufferBytesAvailableForReading > circularBufferBytes) { circularBufferBytesAvailableForReading = circularBufferBytes; } int circularBufferBytesAvailableForCapturing = circularBufferBytes - circularBufferBytesAvailableForReading; //int toRead = readPosition - m_CircularBufferReadPositon; //if (toRead < 0) // toRead += m_CircularBuffer.Caps.BufferBytes; //toRead -= (toRead % (m_CircularBuffer.Caps.BufferBytes / NOTIFICATIONS)); //if (toRead <= 0) //{ // Console.WriteLine(string.Format("BAD toRead {0}", toRead)); // continue; //} #if !FORCE_SINGLE_NOTIFICATION_EVENT if (eventIndex >= 0) { DebugFix.Assert(circularBufferBytesAvailableForReading == notifyChunk); int pos = eventIndex * notifyChunk; //DebugFix.Assert(pos == m_CircularBufferReadPositon); if (m_CircularBufferReadPositon != pos) { #if DEBUG Console.WriteLine("READ POS ADJUST: " + m_CircularBufferReadPositon + " != " + pos + " // " + notifyChunk + " -- " + (pos - m_CircularBufferReadPositon)); #endif m_CircularBufferReadPositon = pos; } } #endif #if USE_SHARPDX if (incomingPcmData == null) { Console.WriteLine("ALLOCATING incomingPcmData"); incomingPcmData = new byte[circularBufferBytesAvailableForReading]; } else if (incomingPcmData.Length < circularBufferBytesAvailableForReading) { Console.WriteLine("incomingPcmData.resize"); Array.Resize(ref incomingPcmData, circularBufferBytesAvailableForReading); } DebugFix.Assert(circularBufferBytesAvailableForReading <= incomingPcmData.Length); m_CircularBuffer.Read(incomingPcmData, 0, circularBufferBytesAvailableForReading, m_CircularBufferReadPositon, LockFlags.None); #else // !USE_SHARPDX byte[] incomingPcmData = (byte[])m_CircularBuffer.Read(m_CircularBufferReadPositon, typeof(byte), LockFlag.None, circularBufferBytesAvailableForReading); DebugFix.Assert(circularBufferBytesAvailableForReading == incomingPcmData.Length); #endif #if FORCE_SINGLE_NOTIFICATION_EVENT if (!lastFlush && m_DO_LOG_CircularBufferNotificationTimerMessage) { String msg = "DO_LOG_CircularBufferNotificationTimerMessage:: circularBufferBytes @ m_CircularBufferReadPositon # circularBufferCapturePosition - circularBufferBytesAvailableForReading / notifyChunk $ incomingPcmData.Length: " + circularBufferBytes + " @ " + m_CircularBufferReadPositon + " # " + circularBufferCapturePosition + " - " + circularBufferBytesAvailableForReading + " / " + notifyChunk + " $ " + (incomingPcmData == null ? "NULL" : ("" + incomingPcmData.Length)); #if DEBUG Console.WriteLine(msg); #endif CircularBufferNotificationTimerMessageHandler del_ = CircularBufferNotificationTimerMessage; if (del_ != null) { del_(this, new CircularBufferNotificationTimerMessageEventArgs(msg)); } } #endif //if (m_CircularBuffer != null && m_CircularBuffer.Capturing) //{ // int capturePosition; // int readPosition; // m_CircularBuffer.GetCurrentPosition(out capturePosition, out readPosition); // return // RecordingPCMFormat.ConvertBytesToTime(m_TotalRecordedBytes + capturePosition - // m_CircularBufferReadPositon); //} int length = circularBufferBytesAvailableForReading; DebugFix.Assert(length <= incomingPcmData.Length); if (length > incomingPcmData.Length) { length = incomingPcmData.Length; } if (m_TotalRecordedBytes >= (ulong.MaxValue - (ulong)length)) { #if DEBUG Debugger.Break(); #endif //DEBUG // Oh oh! :( if (CurrentState == State.Monitoring) { m_TotalRecordedBytes = 0; #if FORCE_SINGLE_NOTIFICATION_EVENT m_PreviousTotalRecordedBytes = 0; #endif } } else { if (CurrentState == State.Recording) { if (m_RecordingFileWriter == null) { string parentDir = Path.GetDirectoryName(m_RecordedFilePath); if (!Directory.Exists(parentDir)) { Directory.CreateDirectory(parentDir); //FileDataProvider.CreateDirectory(parentDir); } //FileInfo fi = new FileInfo(m_RecordedFilePath); //fi.FullName m_RecordingFileWriter = new BinaryWriter(File.OpenWrite(m_RecordedFilePath)); } m_RecordingFileWriter.BaseStream.Position = (long)m_TotalRecordedBytes + (long)m_RecordedFileRiffHeaderSize; // m_RecordingFileWriter.BaseStream.Length; m_RecordingFileWriter.Write(incomingPcmData, 0, length); } m_TotalRecordedBytes += (ulong)length; } m_CircularBufferReadPositon += length; m_CircularBufferReadPositon %= circularBufferBytes; PcmDataBufferAvailableHandler del = PcmDataBufferAvailable; if (del != null) { //if (m_PcmDataBuffer.Length != incomingPcmData.Length) //{ // //Console.WriteLine(string.Format(">>>>> Resizing buffer: m_PcmDataBuffer = {0}, incomingPcmData = {1}",m_PcmDataBuffer.Length, incomingPcmData.Length)); // Array.Resize(ref m_PcmDataBuffer, incomingPcmData.Length); //} //Array.Copy(incomingPcmData, m_PcmDataBuffer, m_PcmDataBuffer.Length); int min = Math.Min(m_PcmDataBufferLength, length); //Array.Copy(incomingPcmData, m_PcmDataBuffer, min); Buffer.BlockCopy(incomingPcmData, 0, m_PcmDataBuffer, 0, min); m_PcmDataBufferAvailableEventArgs.PcmDataBuffer = m_PcmDataBuffer; m_PcmDataBufferAvailableEventArgs.PcmDataBufferLength = min; del(this, m_PcmDataBufferAvailableEventArgs); } return(length); }