public void HandleEvent(EventType eventType, KStudioEvent eventObj) { if ((eventType == EventType.Monitor) && (eventObj != null)) { if ((eventObj.EventStreamDataTypeId == HackKStudioEventStreamDataTypeIds.SystemAudio) || (eventObj.EventStreamDataTypeId == HackKStudioEventStreamDataTypeIds.SystemAudioMonitor) || (eventObj.EventStreamDataTypeId == HackKStudioEventStreamDataTypeIds.TitleAudio) || (eventObj.EventStreamDataTypeId == HackKStudioEventStreamDataTypeIds.TitleAudioMonitor)) { lock (this.lockObj) { this.sharedAudioFrame = null; this.beamConfidence = 0.0f; this.beamAngle = 0.0f; this.frameTime = TimeSpan.Zero; uint bufferSize; IntPtr bufferPtr; eventObj.AccessUnderlyingEventDataBuffer(out bufferSize, out bufferPtr); if (bufferSize >= cAudioFrameSizeMinimum) { this.sharedAudioFrame = eventObj.GetRetainableEventDataBuffer(); this.frameTime = eventObj.RelativeTime; unsafe { nui.AUDIO_FRAME * pFrame = (nui.AUDIO_FRAME *)bufferPtr.ToPointer(); nui.AUDIO_SUBFRAME * pSubFrame = &(pFrame->FirstSubFrame); nui.AUDIO_BEAM_FRAME_HEADER *pBeamHeader = &(pSubFrame->BeamFrameHeader); this.beamConfidence = pBeamHeader->BeamAngleConfidence; this.beamAngle = pBeamHeader->BeamAngle; for (int i = 0; i < pFrame->SubFrameCount; ++i) { UpdateChartSubFrame(pSubFrame + i); } } } } } } }
public void Render2D(EventType eventType, IPluginViewSettings pluginViewSettings, viz.Context context, viz.Texture texture, float left, float top, float width, float height) { if (eventType == EventType.Monitor) { lock (this.lockObj) { if (this.frameTime == TimeSpan.MinValue) { return; } AudioPlugin2DViewSettings audioPluginViewSettings = pluginViewSettings as AudioPlugin2DViewSettings; if (audioPluginViewSettings != null) { float x = 10; // margin on left float chartX = x + 100; // offset to chart rendering float y = 10; // margin on top float deltaY = 24; // height of each row // chart window size float chartHeight = 20; float chartWidth = 600; // max value in chart, bigger ones got capped float chartValueCap = 0.02f; // special color for current frame in time line viz.Vector currentFrameColor = new viz::Vector(1, 0, 0, 1); viz.Vector?color = null; if ((audioPluginViewSettings.RenderBeam) && (this.font != null)) { string str; if (this.beamConfidence > 0.0f) { str = string.Format(CultureInfo.CurrentCulture, Strings.Audio_Beam_Label_Format, this.beamAngle); // TODO: option for other display? like degrees? } else { str = Strings.Audio_Beam_Invalid_Label; } this.font.DrawText(str, x, y, color); } y += deltaY; if (this.sharedAudioFrame != null) { if (this.sharedAudioFrame.Size >= cAudioFrameSizeMinimum) { IntPtr bufferPtr = this.sharedAudioFrame.Buffer; unsafe { nui.AUDIO_FRAME * pFrame = (nui.AUDIO_FRAME *)bufferPtr.ToPointer(); nui.AUDIO_SUBFRAME *pSubFrame = &(pFrame->FirstSubFrame); ulong currentFirstFrameTimeStamp = (ulong)this.frameTime.Ticks; ulong timeStampOffset = currentFirstFrameTimeStamp - pSubFrame->TimeCounter; ulong currentLastFrameTimeStamp = pSubFrame[pFrame->SubFrameCount - 1].TimeCounter + timeStampOffset; #if TODO_LOCAL_PLAYBACK if ((this.timelineBegin != 0) || (this.timelineEnd != 0)) { // timeline rendering if (this.timelineDirty) { this.timelineData->Sort(new System.Comparison <TimelineEntry>(TimelineEntry.Compare)); timelineDirty = false; } if (audioPluginViewSettings.RenderOutput) { if (this.font != null) { this.font.DrawText(this.outString, x, y, color); for (int i = 0; i < this.timelineData.Count; i++) { ulong timeStamp = this.timelineData[i]->TimeStamp; if (timeStamp < this.timelineBegin) { continue; } if (timeStamp > this.timelineEnd) { break; } float normalizedValue = (float)(Math.Min(chartValueCap, Math.Abs(this.timelineData[i].Output)) / chartValueCap); float topLeftX = chartX + (timeStamp - this.timelineBegin) * chartWidth / (this.timelineEnd - this.timelineBegin); float topLeftY = y + (1 - normalizedValue) * chartHeight / 2; float chartBarHeight = Math.Max(normalizedValue * chartHeight, 1.0f); bool isCurrentFrame = (timeStamp >= currentFirstFrameTimeStamp && timeStamp <= currentLastFrameTimeStamp); float barZ = isCurrentFrame ? 0 : 0.01f; // put current frame at a smaller z so it's always visible float barWidth = isCurrentFrame ? 2.0f : 1.0f; // make current frame tick bold viz::Vector?barColor = isCurrentFrame ? currentFrameColor : null; if (this.overlay != null) { this.overlay->DrawColor(topLeftX, topLeftY, barWidth, chartBarHeight, barZ, barColor); } } } y += deltaY; } for (int iMIC = 0; iMIC < NUIP_AUDIO_NUM_MIC; iMIC++) { if ((int)renderOptionType == (int)RenderOptionType::MIC0 + iMIC) { _font->DrawText(renderOptionName, x, y, color); for (int iSample = 0; iSample < _timelineData->Count; iSample++) { UInt64 timeStamp = _timelineData[iSample]->TimeStamp; if (timeStamp < _timelineBegin) { continue; } if (timeStamp > _timelineEnd) { break; } float normalizedValue = min(chartValueCap, fabs(_timelineData[iSample]->MIC[iMIC])) / chartValueCap; float topLeftX = chartX + (timeStamp - _timelineBegin) * chartWidth / (_timelineEnd - _timelineBegin); float topLeftY = y + (1 - normalizedValue) * chartHeight / 2; float chartBarHeight = max(normalizedValue * chartHeight, 1.0f); bool isCurrentFrame = (timeStamp >= currentFirstFrameTimeStamp && timeStamp <= currentLastFrameTimeStamp); float barZ = isCurrentFrame ? 0 : 0.01f; float barWidth = isCurrentFrame ? 2.0f : 1.0f; Nullable <Xbox::Kinect::Viz::Vector> barColor; if (isCurrentFrame) { barColor = currentFrameColor; } _overlay->DrawColor(topLeftX, topLeftY, barWidth, chartBarHeight, barZ, barColor); } } y += deltaY; } for (int iSPK = 0; iSPK < NUIP_AUDIO_NUM_SPK; iSPK++) { if ((int)renderOptionType == (int)RenderOptionType::SPK0 + iSPK) { _font->DrawText(renderOptionName, x, y, color); for (int iSample = 0; iSample < _timelineData->Count; iSample++) { UInt64 timeStamp = _timelineData[iSample]->TimeStamp; if (timeStamp < _timelineBegin) { continue; } if (timeStamp > _timelineEnd) { break; } float normalizedValue = min(chartValueCap, fabs(_timelineData[iSample]->SPK[iSPK])) / chartValueCap; float topLeftX = chartX + (timeStamp - _timelineBegin) * chartWidth / (_timelineEnd - _timelineBegin); float topLeftY = y + (1 - normalizedValue) * chartHeight / 2; float chartBarHeight = max(normalizedValue * chartHeight, 1.0f); bool isCurrentFrame = (timeStamp >= currentFirstFrameTimeStamp && timeStamp <= currentLastFrameTimeStamp); float barZ = isCurrentFrame ? 0 : 0.01f; float barWidth = isCurrentFrame ? 2.0f : 1.0f; Nullable <Xbox::Kinect::Viz::Vector> barColor; if (isCurrentFrame) { barColor = currentFrameColor; } _overlay->DrawColor(topLeftX, topLeftY, barWidth, chartBarHeight, barZ, barColor); } } y += deltaY; } } else #endif // TODO_LOCAL_PLAYBACK { // live rendering float barWidth = 1; UInt64 timeSpan = 2 * 10 * 1000 * 1000; // in 100ns unit if (audioPluginViewSettings.RenderOutput) { if (this.font != null) { this.font.DrawText(this.outString, x, y, color); } if (this.outChart != null) { this.outChart.RenderBar(chartX, y, chartWidth, chartHeight, 0, barWidth, color, currentLastFrameTimeStamp, timeSpan, 0, chartValueCap); } y += deltaY; } if (this.micCharts != null) { for (int i = 0; i < this.micCharts.Length; ++i) { if (audioPluginViewSettings.GetTrackOption((AudioTrack)(AudioTrack.Mic0 + i))) { if (this.font != null) { this.font.DrawText(this.micStrings[i], x, y, color); } this.micCharts[i].RenderBar(chartX, y, chartWidth, chartHeight, 0, barWidth, color, currentLastFrameTimeStamp, timeSpan, 0, chartValueCap); y += deltaY; } } } if (this.speakerCharts != null) { for (int i = 0; i < this.speakerCharts.Length; ++i) { if (audioPluginViewSettings.GetTrackOption((AudioTrack)(AudioTrack.SpeakerL + i))) { if (this.font != null) { this.font.DrawText(this.speakerStrings[i], x, y, color); } this.speakerCharts[i].RenderBar(chartX, y, chartWidth, chartHeight, 0, barWidth, color, currentLastFrameTimeStamp, timeSpan, 0, chartValueCap); y += deltaY; } } } } } } } } } } }