private void LoadEvents() { if (this.events == null) { KStudioSeekableEventStream seekableStream = this.stream as KStudioSeekableEventStream; if (seekableStream != null) { IReadOnlyList <KStudioEventHeader> eventHeaders = seekableStream.EventHeaders; this.events = new EventData[eventHeaders.Count]; bool doFrameNumber = false; if (seekableStream.TagSize >= sizeof(uint)) { // At this time, assume if there is at least 4 bytes of tag data that it is a frame number doFrameNumber = true; } int count = eventHeaders.Count; if (count > 0) { ulong tick; uint eventIndex; { KStudioEventHeader eventHeader = eventHeaders[0]; tick = (ulong)eventHeader.RelativeTime.Ticks * EventStreamState.cTimeSpanTicksToTimelineTicks; eventIndex = eventHeader.EventIndex; } int lastIndex = count - 1; for (int i = 0; i < lastIndex; ++i) { KStudioEventHeader eventHeader = eventHeaders[i + 1]; ulong nextTick = (ulong)eventHeader.RelativeTime.Ticks * EventStreamState.cTimeSpanTicksToTimelineTicks; uint? frameNumber = null; if (doFrameNumber) { uint bufferSize; IntPtr bufferPtr; eventHeader.AccessUnderlyingTagDataBuffer(out bufferSize, out bufferPtr); Debug.Assert(bufferSize >= sizeof(uint)); unsafe { frameNumber = *((uint *)bufferPtr.ToPointer()); } } EventData eventDataNode = new EventData((int)eventIndex, frameNumber, tick, nextTick - tick); tick = nextTick; eventIndex = eventHeader.EventIndex; this.events[i] = eventDataNode; } { KStudioEventHeader eventHeader = eventHeaders[lastIndex]; uint?frameNumber = null; if (doFrameNumber) { uint bufferSize; IntPtr bufferPtr; eventHeader.AccessUnderlyingTagDataBuffer(out bufferSize, out bufferPtr); Debug.Assert(bufferSize >= sizeof(uint)); unsafe { frameNumber = *((uint *)bufferPtr.ToPointer()); } } ulong lastDuration; if (this.duration == 0) { lastDuration = EventStreamState.cLastEventDuration; } else { lastDuration = this.duration - tick; } EventData eventDataNode = new EventData((int)eventIndex, frameNumber, tick, lastDuration); this.events[lastIndex] = eventDataNode; } #if TODODEB EventHandler handler = this.TimeRangeChanged; if (handler != null) { handler(this, EventArgs.Empty); } handler = this.RenderInvalidated; if (handler != null) { handler(this, EventArgs.Empty); } #endif } } this.readOnlyEvents = Array.AsReadOnly(this.events); } }
public override void Extract(string outputPath) { KStudioSeekableEventStream stream = (KStudioSeekableEventStream)_stream; IReadOnlyList <KStudioEventHeader> headers = stream.EventHeaders; int frameCount = (int)stream.EventCount; double[] audioTiming = new double[frameCount]; const int eventFrameSize = 14432; // Size for a single audio event frame const int frameSize = 1024; // The size of the actual audio data in an event frame int dataSize = 0; int bytePos = 0; // DEBUG int missedFrames = 0; double cumulativeTime = 0; double lDiff = 0; KStudioEventHeader lHeader = null; // END DEBUG // Hacky counting of total data size for (int i = 0; i < frameCount; i++) { KStudioEventHeader header = headers[i]; int j = eventFrameSize; double missedTime = 0; double diff = header.RelativeTime.TotalMilliseconds; /* DEBUG */ if (lHeader != null) { diff = header.RelativeTime.TotalMilliseconds - lHeader.RelativeTime.TotalMilliseconds; if (diff > lDiff) { lDiff = diff; } } lHeader = header; /* END DEBUG */ do { dataSize += frameSize; j += eventFrameSize - 16; missedTime += 16; } while (j <= (int)header.EventDataSize); missedTime = diff - missedTime; cumulativeTime += missedTime; while (cumulativeTime > 16) { cumulativeTime -= 16; missedFrames++; } } // Calculate additional bytes needed //int numBytes = (int) totalMissedTime / 16 * 1024; int numBytes = missedFrames * frameSize; if (numBytes > 0) { dataSize += numBytes; } // DEBUG missedFrames = 0; cumulativeTime = 0; KStudioEvent lEvent = null; // END DEBUG byte[] rawAudio = new byte[dataSize]; for (uint i = 0; i < frameCount; i++) { int j = eventFrameSize; var currEvent = stream.ReadEvent(i); byte[] rawBuffer = new byte[currEvent.EventDataSize]; int offset = 96; double diff = currEvent.RelativeTime.TotalMilliseconds; double missedTime = 0; if (lEvent != null) { diff = currEvent.RelativeTime.TotalMilliseconds - lEvent.RelativeTime.TotalMilliseconds; if (diff > lDiff) { lDiff = diff; } } lEvent = currEvent; audioTiming[i] = currEvent.RelativeTime.TotalMilliseconds; currEvent.CopyEventDataToArray(rawBuffer, 0); do { Array.Copy(rawBuffer, offset, rawAudio, bytePos, frameSize); bytePos += frameSize; j += eventFrameSize - 16; offset += eventFrameSize - 16; missedTime += 16; } while (j <= (int)currEvent.EventDataSize); // If there is any missed time, add it here. missedTime = diff - missedTime; cumulativeTime += missedTime; while (cumulativeTime > 16) { cumulativeTime -= 16; missedFrames++; bytePos += frameSize; } // Update progress OnProgressUpdated(new KinectFileProgressChangedEventArgs { Progress = (int)((float)(i + 1) / frameCount * 100), StatusName = Name }); } string filepath = outputPath + "/Kinect_Output"; Directory.CreateDirectory(filepath); File.WriteAllBytes(filepath + "/raw_audio.wav", rawAudio); // Write timings Utils.WriteTimingToFile(filepath + "/audio_timing.txt", audioTiming); }