Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/slmml/Sequencer.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 138 - (show annotations) (download)
Sat Aug 22 13:31:42 2009 UTC (14 years, 6 months ago) by hikarin
File size: 10729 byte(s)
[ocmml/slmml] * implemented Ring Modulator and Sync
1 /*
2 Copyright (c) 2009, hkrn All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 Redistributions of source code must retain the above copyright notice, this
8 list of conditions and the following disclaimer. Redistributions in binary
9 form must reproduce the above copyright notice, this list of conditions and
10 the following disclaimer in the documentation and/or other materials
11 provided with the distribution. Neither the name of the hkrn nor
12 the names of its contributors may be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
19 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
25 DAMAGE.
26 */
27
28 //
29 // $Id$
30 //
31
32 using System;
33 using System.Collections.Generic;
34 using System.Globalization;
35 using System.IO;
36 using System.Windows.Media;
37
38 namespace SlMML
39 {
40 enum SequencerStep
41 {
42 None,
43 Pre,
44 Track,
45 Post
46 }
47
48 public sealed class Sequencer : MediaStreamSource
49 {
50 #region ���������������
51 public const int BUFFER_SIZE = 8192;
52 public const int BUFFER_ARRAY_SIZE = 2;
53 private const int BLOCK_ALIGNMENT = 2 * sizeof(short);
54 private const int BUFFER_BLOCK_SIZE = BUFFER_SIZE * BLOCK_ALIGNMENT;
55 private const string WAVE_HEADER = "0100020044ac000010b10200040010000000";
56 #endregion
57
58 #region ���������������������������������������������������������
59 /// <summary>
60 /// ���������������������������������������������������������Sequencer������������������������������������
61 /// </summary>
62 /// <param name="multiple">���������������������������</param>
63 public Sequencer(int multiple)
64 {
65 m_bufferSize = BUFFER_SIZE * multiple;
66 m_buffer = new double[m_bufferSize << 1];
67 m_tracks = new List<Track>();
68 m_multiple = multiple;
69 m_mediaSampleAttributes = new Dictionary<MediaSampleAttributeKeys, string>();
70 MasterVolume = 100;
71 Channel.Initialize(BUFFER_SIZE * multiple);
72 }
73 #endregion
74
75 #region MediaStreamSource������������������������������
76 protected override void OpenMediaAsync()
77 {
78 m_timestampBlock = (long)Math.Round((decimal)(TimeSpan.FromSeconds(1).Ticks / (BUFFER_BLOCK_SIZE * m_multiple)));
79 Dictionary<MediaStreamAttributeKeys, string> mediaStreamAttributes = new Dictionary<MediaStreamAttributeKeys, string>();
80 mediaStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = WAVE_HEADER;
81 description = new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes);
82 Dictionary<MediaSourceAttributesKeys, string> mediaSourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>();
83 mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = false.ToString();
84 mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = m_tracks[Track.TEMPO_TRACK].Duration.TimeSpan.Ticks.ToString(CultureInfo.InvariantCulture);
85 List<MediaStreamDescription> availableMediaStreams = new List<MediaStreamDescription>();
86 availableMediaStreams.Add(new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes));
87 ReportOpenMediaCompleted(mediaSourceAttributes, availableMediaStreams);
88 ReportGetSampleProgress(0);
89 GetSamples();
90 }
91
92 protected override void CloseMedia()
93 {
94 }
95
96 protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
97 {
98 ReportGetDiagnosticCompleted(diagnosticKind, 0);
99 }
100
101 protected override void GetSampleAsync(MediaStreamType mediaStreamType)
102 {
103 MediaStreamSample sample;
104 if (m_endCount > 1)
105 {
106 sample = new MediaStreamSample(description, null, 0, 0, 0, m_mediaSampleAttributes);
107 ReportGetSampleCompleted(sample);
108 }
109 else
110 {
111 using (MemoryStream stream = new MemoryStream(BUFFER_BLOCK_SIZE))
112 using (BinaryWriter writer = new BinaryWriter(stream))
113 {
114 int index = m_count * BUFFER_SIZE;
115 double volume = Math.Min(MasterVolume, 100) / 100;
116 for (int i = index; i < index + BUFFER_SIZE; i++)
117 {
118 int bufferIndex = i << 1;
119 writer.Write((m_buffer[bufferIndex] * volume).ToShort());
120 writer.Write((m_buffer[bufferIndex + 1] * volume).ToShort());
121 }
122 m_count++;
123 m_timestampIndex += m_timestampBlock;
124 sample = new MediaStreamSample(description, stream, 0, BUFFER_BLOCK_SIZE, m_timestampIndex, m_mediaSampleAttributes);
125 ReportGetSampleCompleted(sample);
126 }
127 }
128 if (m_count == m_multiple)
129 {
130 GetSamples();
131 m_count = 0;
132 if ((m_tracks[Track.TEMPO_TRACK]).End)
133 m_endCount++;
134 }
135 }
136
137 protected override void SeekAsync(long seekToTime)
138 {
139 ReportSeekCompleted(seekToTime);
140 }
141
142 protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
143 {
144 ReportSwitchMediaStreamCompleted(mediaStreamDescription);
145 }
146 #endregion
147
148 #region ���������������������������
149 /// <summary>
150 /// ������������������������������������������
151 /// </summary>
152 public void ClearTracks()
153 {
154 m_tracks.Clear();
155 }
156
157 /// <summary>
158 /// ������������������������������
159 /// </summary>
160 /// <param name="track"></param>
161 public void AddTrack(Track track)
162 {
163 m_tracks.Add(track);
164 }
165
166 /// <summary>
167 /// ������������������������������������������������������������������
168 /// </summary>
169 /// <param name="number">������������</param>
170 public void CreatePipes(int number)
171 {
172 Channel.CreatePipes(number);
173 }
174
175 /// <summary>
176 /// ������������������������������������������������������������������������
177 /// </summary>
178 /// <param name="number">������������</param>
179 public void CreateSyncSources(int number)
180 {
181 Channel.CreateSyncSources(number);
182 }
183 #endregion
184
185 #region ������������������������������
186 private void GetSamples()
187 {
188 bool loop = true;
189 int blen = Math.Min((BUFFER_SIZE << 2), m_bufferSize);
190 int offset = 0;
191 int trackIndex = 0;
192 int trackCount = m_tracks.Count;
193 SequencerStep step = SequencerStep.Pre;
194 while (loop)
195 {
196 switch (step)
197 {
198 case SequencerStep.Pre:
199 // ������������������������������������0������������������
200 for (int i = (m_bufferSize << 1) - 1; i >= 0; i--)
201 m_buffer[i] = (0.0).ToShort();
202 if (trackCount > 0)
203 {
204 Track track = m_tracks[Track.TEMPO_TRACK];
205 track.GetSamples(ref m_buffer, 0, m_bufferSize, false);
206 }
207 step = SequencerStep.Track;
208 trackIndex = Track.FIRST_TRACK;
209 offset = 0;
210 break;
211 case SequencerStep.Track:
212 // ������������������������������������������������������������������
213 if (trackIndex >= trackCount)
214 step = SequencerStep.Post;
215 else
216 {
217 Track track = m_tracks[trackIndex];
218 track.GetSamples(ref m_buffer, offset, offset + blen, true);
219 offset += blen;
220 if (offset >= m_bufferSize)
221 {
222 offset = 0;
223 trackIndex++;
224 //m_buffered = (m_trackIndex + 1.0) / (trackCount + 1.0);
225 }
226 }
227 break;
228 case SequencerStep.Post:
229 // ���������������
230 loop = false;
231 break;
232 }
233 }
234 }
235 #endregion
236
237 #region ������������������������������
238 /// <summary>
239 /// ���������������������������������
240 /// </summary>
241 /// <remarks>
242 /// ���������������������������������������������������������������
243 /// </remarks>
244 public uint MasterVolume
245 {
246 get;
247 set;
248 }
249 #endregion
250
251 #region ���������������������������
252 private Dictionary<MediaSampleAttributeKeys, string> m_mediaSampleAttributes;
253 private MediaStreamDescription description;
254 private List<Track> m_tracks;
255 private double[] m_buffer;
256 private long m_timestampIndex;
257 private long m_timestampBlock;
258 private int m_bufferSize;
259 private int m_multiple;
260 private int m_count;
261 private int m_endCount;
262 #endregion
263 }
264 }

Properties

Name Value
svn:keywords Id

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