2013/01/05(土)いろんなとけい
今日のアウトプット。
C#でいろんな時計をつくってみる。
using System; using System.Collections.Generic; using System.Text; namespace Tsukikage.GameSDK.Util { public interface IReferenceClock : IDisposable { void Initialize(); double GetCurrentTime(); } public class StopwatchClock : IReferenceClock { System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); public void Initialize() { stopwatch.Start(); } public double GetCurrentTime() { return stopwatch.Elapsed.TotalMilliseconds; } public void Dispose() { GC.SuppressFinalize(this); } } public class DateTimeClock : IReferenceClock { DateTime start = DateTime.Now; public void Initialize() { this.start = DateTime.Now; } public double GetCurrentTime() { return (DateTime.Now - this.start).TotalMilliseconds; } public void Dispose() { GC.SuppressFinalize(this); } } public class TimeGetTimeClock : IReferenceClock { int start = 0; public void Initialize() { timeBeginPeriod(1); start = timeGetTime(); } public double GetCurrentTime() { return timeGetTime() - start; } public void Dispose() { GC.SuppressFinalize(this); } [System.Runtime.InteropServices.DllImport("winmm", EntryPoint = "timeBeginPeriod")] [System.Security.SuppressUnmanagedCodeSecurity] static extern int timeBeginPeriod(int p); [System.Runtime.InteropServices.DllImport("winmm", EntryPoint = "timeGetTime")] [System.Security.SuppressUnmanagedCodeSecurity] static extern int timeGetTime(); } public class QueryPerformanceCounterClock : IReferenceClock { long start = 0L; long freq = 1L; public void Initialize() { QueryPerformanceFrequency(out freq); QueryPerformanceCounter(out start); } public double GetCurrentTime() { long cur; QueryPerformanceCounter(out cur); return ((cur - start) * 1000.0 / freq); } public void Dispose() { GC.SuppressFinalize(this); } [System.Runtime.InteropServices.DllImport("kernel32.dll")] [System.Security.SuppressUnmanagedCodeSecurity] extern static short QueryPerformanceCounter(out long x); [System.Runtime.InteropServices.DllImport("kernel32.dll")] [System.Security.SuppressUnmanagedCodeSecurity] extern static short QueryPerformanceFrequency(out long x); } public class AudioDeviceClock : IReferenceClock { Tsukikage.Audio.AudioDevice audioDevice; Tsukikage.Audio.IAudioBuffer buffer; System.Threading.ManualResetEvent disposed; System.Threading.Thread thread; int trigCount; public AudioDeviceClock(Tsukikage.Audio.AudioDevice device) { this.audioDevice = device; } public void Initialize() { trigCount = 0; int freq = 44100, ch = 1, bps = 16; // 1 sec empty audio buffer buffer = audioDevice.CreateBuffer(freq, ch, bps, freq * ch * bps / 8); buffer.Play(true); this.disposed = new System.Threading.ManualResetEvent(false); this.thread = new System.Threading.Thread(() => { bool prev = true; while (!disposed.WaitOne(100)) { // pata pata pata ... bool cur = buffer.PlayPosition < buffer.Length / 2; if ((!prev && cur) || (prev && !cur)) { prev ^= true; trigCount++; } } }); this.thread.Priority = System.Threading.ThreadPriority.Highest; this.thread.Start(); } public double GetCurrentTime() { int curPos = buffer.PlayPosition; int bufOrign = curPos < buffer.Length / 2 ? trigCount + 1 & ~1 : trigCount & ~1; return bufOrign * 500 + curPos / (buffer.Length / 1000.0); // in millisecond } public void Dispose() { if (thread != null) { disposed.Set(); thread.Join(); disposed.Close(); disposed = null; thread = null; } if (buffer != null) { buffer.Dispose(); buffer = null; } GC.SuppressFinalize(this); } } }