Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Sequencer.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (hide annotations) (download)
Thu Apr 2 14:32:07 2009 UTC (15 years ago) by hikarin
File size: 7839 byte(s)
[ocmml/slmml] * fixed a bug that causes unfinished stopping
1 hikarin 37 using System;
2     using System.Collections.Generic;
3 hikarin 48 using System.Globalization;
4 hikarin 37 using System.IO;
5     using System.Windows.Media;
6    
7     namespace SlMML
8     {
9     enum SequencerStep
10     {
11     None,
12     Pre,
13     Track,
14     Post
15     }
16    
17     public sealed class Sequencer : MediaStreamSource
18     {
19     #region 定数の定義
20     public static readonly int BUFFER_SIZE = 8192;
21     public static readonly int BUFFER_ARRAY_SIZE = 2;
22 hikarin 47 private static readonly int BLOCK_ALIGNMENT = 2 * sizeof(short);
23     private static readonly int BUFFER_BLOCK_SIZE = BUFFER_SIZE * BLOCK_ALIGNMENT;
24 hikarin 37 private static readonly string WAVE_HEADER = "0100020044ac000010b10200040010000000";
25     #endregion
26    
27     #region コンストラクタおよびデストラクタの定義
28     public Sequencer(int multiple)
29     {
30     m_bufferSize = BUFFER_SIZE * multiple;
31     m_buffer = new short[m_bufferSize << 1];
32     m_tracks = new List<Track>();
33     m_multiple = multiple;
34     m_mediaSampleAttributes = new Dictionary<MediaSampleAttributeKeys, string>();
35     MasterVolume = 100;
36     Channel.Initialize(BUFFER_SIZE * multiple);
37     }
38     #endregion
39    
40     #region MediaStreamSourceの派生メソッドの定義
41     protected override void OpenMediaAsync()
42     {
43 hikarin 48 m_timestampBlock = (long)Math.Round((decimal)(TimeSpan.FromSeconds(1).Ticks / (BUFFER_BLOCK_SIZE * m_multiple)));
44 hikarin 37 Dictionary<MediaStreamAttributeKeys, string> mediaStreamAttributes = new Dictionary<MediaStreamAttributeKeys, string>();
45     mediaStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = WAVE_HEADER;
46     description = new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes);
47     Dictionary<MediaSourceAttributesKeys, string> mediaSourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>();
48     mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = false.ToString();
49 hikarin 48 mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = m_tracks[Track.TEMPO_TRACK].Duration.TimeSpan.Ticks.ToString(CultureInfo.InvariantCulture);
50 hikarin 37 List<MediaStreamDescription> availableMediaStreams = new List<MediaStreamDescription>();
51     availableMediaStreams.Add(new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes));
52     ReportOpenMediaCompleted(mediaSourceAttributes, availableMediaStreams);
53     ReportGetSampleProgress(0);
54     GetSamples();
55     }
56    
57     protected override void CloseMedia()
58     {
59     }
60    
61     protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
62     {
63     ReportGetDiagnosticCompleted(diagnosticKind, 0);
64     }
65    
66     protected override void GetSampleAsync(MediaStreamType mediaStreamType)
67     {
68     MediaStreamSample sample;
69 hikarin 53 if (m_endCount > 1)
70 hikarin 37 {
71     sample = new MediaStreamSample(description, null, 0, 0, 0, m_mediaSampleAttributes);
72     ReportGetSampleCompleted(sample);
73     }
74     else
75 hikarin 47 {
76 hikarin 53 using (MemoryStream stream = new MemoryStream(BUFFER_BLOCK_SIZE))
77 hikarin 47 using (BinaryWriter writer = new BinaryWriter(stream))
78     {
79     int index = m_count * BUFFER_SIZE;
80     double volume = Math.Min(MasterVolume, 100) / 100;
81     for (int i = index; i < index + BUFFER_SIZE; i++)
82     {
83     int bufferIndex = i << 1;
84     writer.Write((short)(m_buffer[bufferIndex] * volume));
85     writer.Write((short)(m_buffer[bufferIndex + 1] * volume));
86     }
87     m_count++;
88     m_timestampIndex += m_timestampBlock;
89     sample = new MediaStreamSample(description, stream, 0, BUFFER_BLOCK_SIZE, m_timestampIndex, m_mediaSampleAttributes);
90     ReportGetSampleCompleted(sample);
91     }
92     }
93     if (m_count == m_multiple)
94     {
95 hikarin 37 GetSamples();
96 hikarin 47 m_count = 0;
97 hikarin 48 if ((m_tracks[Track.TEMPO_TRACK]).End)
98 hikarin 53 m_endCount++;
99 hikarin 37 }
100     }
101    
102     protected override void SeekAsync(long seekToTime)
103     {
104     ReportSeekCompleted(seekToTime);
105     }
106    
107     protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
108     {
109     ReportSwitchMediaStreamCompleted(mediaStreamDescription);
110     }
111     #endregion
112    
113     #region 公開メソッドの定義
114     public void ClearTracks()
115     {
116     m_tracks.Clear();
117     }
118    
119     public void AddTrack(Track track)
120     {
121     m_tracks.Add(track);
122     }
123    
124     public void CreatePipes(int number)
125     {
126     Channel.CreatePipes(number);
127     }
128     #endregion
129    
130     #region 非公開メソッドの定義
131     private void GetSamples()
132     {
133     bool loop = true;
134     int blen = Math.Min((BUFFER_SIZE << 2), m_bufferSize);
135     int offset = 0;
136     int trackIndex = 0;
137     int trackCount = m_tracks.Count;
138     SequencerStep step = SequencerStep.Pre;
139     while (loop)
140     {
141     switch (step)
142     {
143     case SequencerStep.Pre:
144     for (int i = (m_bufferSize << 1) - 1; i >= 0; i--)
145     m_buffer[i] = (0.0).ToShort();
146     if (trackCount > 0)
147     {
148     Track track = m_tracks[Track.TEMPO_TRACK];
149     track.GetSamples(ref m_buffer, 0, m_bufferSize, false);
150     }
151     step = SequencerStep.Track;
152     trackIndex = Track.FIRST_TRACK;
153     offset = 0;
154     break;
155     case SequencerStep.Track:
156     if (trackIndex >= trackCount)
157     step = SequencerStep.Post;
158     else
159     {
160     Track track = m_tracks[trackIndex];
161     track.GetSamples(ref m_buffer, offset, offset + blen, true);
162     offset += blen;
163     if (offset >= m_bufferSize)
164     {
165     offset = 0;
166     trackIndex++;
167     //m_buffered = (m_trackIndex + 1.0) / (trackCount + 1.0);
168     }
169     }
170     break;
171     case SequencerStep.Post:
172     loop = false;
173     break;
174     }
175     }
176     }
177     #endregion
178    
179     #region 公開プロパティの定義
180     public uint MasterVolume
181     {
182     get;
183     set;
184     }
185     #endregion
186    
187     #region メンバー変数の定義
188     private Dictionary<MediaSampleAttributeKeys, string> m_mediaSampleAttributes;
189     private MediaStreamDescription description;
190     private List<Track> m_tracks;
191     private short[] m_buffer;
192 hikarin 47 private long m_timestampIndex;
193     private long m_timestampBlock;
194 hikarin 37 private int m_bufferSize;
195     private int m_multiple;
196 hikarin 47 private int m_count;
197 hikarin 53 private int m_endCount;
198 hikarin 37 #endregion
199     }
200     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26