public int GetSampleFromTiming(Timing timing) { Timing nextMeterTiming = new Timing(); if (timing < nextMeterTiming) { return(0); } MusicMeterBySample meter = null; for (int i = 0; i < Meters.Length; ++i) { if (i + 1 < Meters.Length) { nextMeterTiming.Set(Meters[i + 1].StartBar); if (timing < nextMeterTiming) { meter = Meters[i]; break; } } else // 最後のメーター { meter = Meters[i]; break; } } return(meter.GetSampleFromTiming(timing)); }
public void Validate(int sampleRate) { IsValid = false; if (Clips.Length == 0 || Clips[0] == null || Meters.Length == 0) { return; } // 最初のメーターをValidateして、EntryPointのサンプル数を計算 Meters[0].OnValidate(sampleRate, 0); EntryPointSample = Meters[0].GetSampleFromTiming(EntryPointTiming); // 後続のメーターすべてをValidate int startSample = EntryPointSample; MusicMeterBySample lastMeter = null; foreach (MusicMeterBySample meter in Meters) { if (lastMeter != null) { startSample += lastMeter.SamplesPerBar * meter.StartBar; } meter.OnValidate(sampleRate, startSample); lastMeter = meter; } ClipEndTiming = lastMeter.GetTimingFromSample(Clips[0].samples); // 波形終わりのタイミングを参考にExitPointを設定する if (ExitPointTiming <= EntryPointTiming || ClipEndTiming < ExitPointTiming) { ExitPointTiming = new Timing(ClipEndTiming); ExitPointTiming.FixToFloor(); } if (ClipEndTiming < LoopEndTiming) { LoopEndTiming = new Timing(ClipEndTiming); LoopEndTiming.FixToFloor(); } if (TransitionType == AutoTransitionType.Loop) { // LoopEndはLoopStartより後じゃないとダメ if (LoopStartTiming >= LoopEndTiming) { LoopEndTiming.Set(ExitPointTiming); } // ExitPointはLoopEndと同一 ExitPointTiming = LoopEndTiming; LoopStartSample = GetSampleFromTiming(LoopStartTiming); LoopEndSample = GetSampleFromTiming(LoopEndTiming); } ExitPointSample = GetSampleFromTiming(ExitPointTiming); IsValid = true; }
protected override void CalcTimingAndFraction(ref Timing just, out float fraction) { if (currentMeter_ == null) { just.Set(-1, 0, 0); fraction = 0; } else { MusicMeterBySample meter = currentMeter_ as MusicMeterBySample; just.Set(meter.GetTimingFromSample(currentSample_)); fraction = (float)(currentSample_ - meter.GetSampleFromTiming(just)) / meter.SamplesPerUnit; } }
MusicMeterBySample GetMeterFromTiming(Timing timing) { MusicMeterBySample res = null; foreach (MusicMeterBySample meter in CurrentSection.Meters) { if (timing.Bar < meter.StartBar) { return(res); } res = meter; } return(res); }
// sync MusicMeterBySample GetMeterFromSample(int sample) { MusicMeterBySample res = null; foreach (MusicMeterBySample meter in CurrentSection.Meters) { if (sample < meter.StartSamples) { return(res); } res = meter; } return(res); }
bool FindSyncPoint(Music.SyncType syncType, int syncFactor, int currentSample, int entryPointSample, out int syncPointSample) { syncPointSample = currentSample; MusicMeterBySample currentMeter = GetMeterFromSample(currentSample); Timing currentTiming = currentMeter != null?currentMeter.GetTimingFromSample(currentSample) : new Timing(); Timing syncPointCandidateTiming = new Timing(currentTiming); switch (syncType) { case Music.SyncType.Immediate: syncPointSample = currentSample + entryPointSample; break; case Music.SyncType.ExitPoint: syncPointSample = CurrentSection.ExitPointSample; if (syncPointSample <= currentSample + entryPointSample) { return(false); } break; case Music.SyncType.Bar: syncPointCandidateTiming.Set(currentTiming.Bar - (currentTiming.Bar - currentMeter.StartBar) % syncFactor + syncFactor, 0, 0); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); while (syncPointSample <= currentSample + entryPointSample) { syncPointCandidateTiming.Add(syncFactor); if (syncPointCandidateTiming > CurrentSection.ExitPointTiming) { return(false); } syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); } break; case Music.SyncType.Beat: syncPointCandidateTiming.Set(currentTiming.Bar, currentTiming.Beat - (currentTiming.Beat % syncFactor) + syncFactor, 0); syncPointCandidateTiming.Fix(currentMeter); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); while (syncPointSample <= currentSample + entryPointSample) { syncPointCandidateTiming.Add(0, syncFactor, 0, currentMeter); syncPointCandidateTiming.Fix(currentMeter); if (syncPointCandidateTiming > CurrentSection.ExitPointTiming) { return(false); } currentMeter = GetMeterFromTiming(syncPointCandidateTiming); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); } break; case Music.SyncType.Unit: syncPointCandidateTiming.Set(currentTiming.Bar, currentTiming.Beat, currentTiming.Unit - (currentTiming.Unit % syncFactor) + syncFactor); syncPointCandidateTiming.Fix(currentMeter); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); while (syncPointSample <= currentSample + entryPointSample) { syncPointCandidateTiming.Add(0, 0, syncFactor, currentMeter); syncPointCandidateTiming.Fix(currentMeter); if (syncPointCandidateTiming > CurrentSection.ExitPointTiming) { return(false); } currentMeter = GetMeterFromTiming(syncPointCandidateTiming); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); } break; case Music.SyncType.Marker: if (0 <= syncFactor && syncFactor < CurrentSection.Markers.Length && CurrentSection.Markers[syncFactor].Timings.Length > 0) { MusicSection.MusicMarker marker = CurrentSection.Markers[syncFactor]; int markerIndex = 0; syncPointCandidateTiming.Set(marker.Timings[markerIndex]); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); while (syncPointSample <= currentSample + entryPointSample) { ++markerIndex; if (marker.Timings.Length <= markerIndex) { return(false); } syncPointCandidateTiming.Set(marker.Timings[markerIndex]); syncPointSample = CurrentSection.GetSampleFromTiming(syncPointCandidateTiming); } } else { print(String.Format("Failed to SetNextSection. {0} section doesn't have Marker[{1}].", CurrentSection.Name, syncFactor)); return(false); } break; } return(true); }