Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Sequencer.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 80 - (hide annotations) (download)
Fri May 1 13:41:09 2009 UTC (14 years, 11 months ago) by hikarin
File size: 9366 byte(s)
[ocmml/slmml] * changed short to double at GetSamples()
1 hikarin 58 /*
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 hikarin 37 using System.Collections.Generic;
34 hikarin 48 using System.Globalization;
35 hikarin 37 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 static readonly int BUFFER_SIZE = 8192;
52     public static readonly int BUFFER_ARRAY_SIZE = 2;
53 hikarin 47 private static readonly int BLOCK_ALIGNMENT = 2 * sizeof(short);
54     private static readonly int BUFFER_BLOCK_SIZE = BUFFER_SIZE * BLOCK_ALIGNMENT;
55 hikarin 37 private static readonly string WAVE_HEADER = "0100020044ac000010b10200040010000000";
56     #endregion
57    
58     #region ���������������������������������������������������������
59     public Sequencer(int multiple)
60     {
61     m_bufferSize = BUFFER_SIZE * multiple;
62 hikarin 80 m_buffer = new double[m_bufferSize << 1];
63 hikarin 37 m_tracks = new List<Track>();
64     m_multiple = multiple;
65     m_mediaSampleAttributes = new Dictionary<MediaSampleAttributeKeys, string>();
66     MasterVolume = 100;
67     Channel.Initialize(BUFFER_SIZE * multiple);
68     }
69     #endregion
70    
71     #region MediaStreamSource������������������������������
72     protected override void OpenMediaAsync()
73     {
74 hikarin 48 m_timestampBlock = (long)Math.Round((decimal)(TimeSpan.FromSeconds(1).Ticks / (BUFFER_BLOCK_SIZE * m_multiple)));
75 hikarin 37 Dictionary<MediaStreamAttributeKeys, string> mediaStreamAttributes = new Dictionary<MediaStreamAttributeKeys, string>();
76     mediaStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = WAVE_HEADER;
77     description = new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes);
78     Dictionary<MediaSourceAttributesKeys, string> mediaSourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>();
79     mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = false.ToString();
80 hikarin 48 mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = m_tracks[Track.TEMPO_TRACK].Duration.TimeSpan.Ticks.ToString(CultureInfo.InvariantCulture);
81 hikarin 37 List<MediaStreamDescription> availableMediaStreams = new List<MediaStreamDescription>();
82     availableMediaStreams.Add(new MediaStreamDescription(MediaStreamType.Audio, mediaStreamAttributes));
83     ReportOpenMediaCompleted(mediaSourceAttributes, availableMediaStreams);
84     ReportGetSampleProgress(0);
85     GetSamples();
86     }
87    
88     protected override void CloseMedia()
89     {
90     }
91    
92     protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
93     {
94     ReportGetDiagnosticCompleted(diagnosticKind, 0);
95     }
96    
97     protected override void GetSampleAsync(MediaStreamType mediaStreamType)
98     {
99     MediaStreamSample sample;
100 hikarin 53 if (m_endCount > 1)
101 hikarin 37 {
102     sample = new MediaStreamSample(description, null, 0, 0, 0, m_mediaSampleAttributes);
103     ReportGetSampleCompleted(sample);
104     }
105     else
106 hikarin 47 {
107 hikarin 53 using (MemoryStream stream = new MemoryStream(BUFFER_BLOCK_SIZE))
108 hikarin 47 using (BinaryWriter writer = new BinaryWriter(stream))
109     {
110     int index = m_count * BUFFER_SIZE;
111     double volume = Math.Min(MasterVolume, 100) / 100;
112     for (int i = index; i < index + BUFFER_SIZE; i++)
113     {
114     int bufferIndex = i << 1;
115 hikarin 80 writer.Write((m_buffer[bufferIndex] * volume).ToShort());
116     writer.Write((m_buffer[bufferIndex + 1] * volume).ToShort());
117 hikarin 47 }
118     m_count++;
119     m_timestampIndex += m_timestampBlock;
120     sample = new MediaStreamSample(description, stream, 0, BUFFER_BLOCK_SIZE, m_timestampIndex, m_mediaSampleAttributes);
121     ReportGetSampleCompleted(sample);
122     }
123     }
124     if (m_count == m_multiple)
125     {
126 hikarin 37 GetSamples();
127 hikarin 47 m_count = 0;
128 hikarin 48 if ((m_tracks[Track.TEMPO_TRACK]).End)
129 hikarin 53 m_endCount++;
130 hikarin 37 }
131     }
132    
133     protected override void SeekAsync(long seekToTime)
134     {
135     ReportSeekCompleted(seekToTime);
136     }
137    
138     protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
139     {
140     ReportSwitchMediaStreamCompleted(mediaStreamDescription);
141     }
142     #endregion
143    
144     #region ���������������������������
145     public void ClearTracks()
146     {
147     m_tracks.Clear();
148     }
149    
150     public void AddTrack(Track track)
151     {
152     m_tracks.Add(track);
153     }
154    
155     public void CreatePipes(int number)
156     {
157     Channel.CreatePipes(number);
158     }
159     #endregion
160    
161     #region ������������������������������
162     private void GetSamples()
163     {
164     bool loop = true;
165     int blen = Math.Min((BUFFER_SIZE << 2), m_bufferSize);
166     int offset = 0;
167     int trackIndex = 0;
168     int trackCount = m_tracks.Count;
169     SequencerStep step = SequencerStep.Pre;
170     while (loop)
171     {
172     switch (step)
173     {
174     case SequencerStep.Pre:
175     for (int i = (m_bufferSize << 1) - 1; i >= 0; i--)
176     m_buffer[i] = (0.0).ToShort();
177     if (trackCount > 0)
178     {
179     Track track = m_tracks[Track.TEMPO_TRACK];
180     track.GetSamples(ref m_buffer, 0, m_bufferSize, false);
181     }
182     step = SequencerStep.Track;
183     trackIndex = Track.FIRST_TRACK;
184     offset = 0;
185     break;
186     case SequencerStep.Track:
187     if (trackIndex >= trackCount)
188     step = SequencerStep.Post;
189     else
190     {
191     Track track = m_tracks[trackIndex];
192     track.GetSamples(ref m_buffer, offset, offset + blen, true);
193     offset += blen;
194     if (offset >= m_bufferSize)
195     {
196     offset = 0;
197     trackIndex++;
198     //m_buffered = (m_trackIndex + 1.0) / (trackCount + 1.0);
199     }
200     }
201     break;
202     case SequencerStep.Post:
203     loop = false;
204     break;
205     }
206     }
207     }
208     #endregion
209    
210     #region ������������������������������
211     public uint MasterVolume
212     {
213     get;
214     set;
215     }
216     #endregion
217    
218     #region ���������������������������
219     private Dictionary<MediaSampleAttributeKeys, string> m_mediaSampleAttributes;
220     private MediaStreamDescription description;
221     private List<Track> m_tracks;
222 hikarin 80 private double[] m_buffer;
223 hikarin 47 private long m_timestampIndex;
224     private long m_timestampBlock;
225 hikarin 37 private int m_bufferSize;
226     private int m_multiple;
227 hikarin 47 private int m_count;
228 hikarin 53 private int m_endCount;
229 hikarin 37 #endregion
230     }
231     }

Properties

Name Value
svn:keywords Id

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