1 /*
2 Ming, an SWF output library
3 Copyright (C) 2002 Opaque Industries - http://www.opaque.net/
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <stdlib.h>
21
22 #include "soundinstance.h"
23 #include "sound.h"
24 #include "block.h"
25 #include "method.h"
26 #include "character.h"
27 #include "libming.h"
28
29
30 typedef struct
31 {
32 unsigned int mark44;
33 unsigned short level0;
34 unsigned short level1;
35 } envPoint;
36
37 struct SWFSoundInstance_s
38 {
39 struct SWFBlock_s block;
40
41 SWFSound sound;
42 unsigned int inPoint;
43 unsigned int outPoint;
44 int numLoops;
45 byte flags;
46 byte numEnvPoints;
47 envPoint *envPoints;
48 };
49
writeSWFSoundInstanceToMethod(SWFBlock block,SWFByteOutputMethod method,void * data)50 void writeSWFSoundInstanceToMethod(SWFBlock block,
51 SWFByteOutputMethod method, void *data)
52 {
53 SWFSoundInstance sound;
54 byte flags;
55 int i;
56
57 // block may be null if we're calling from button.c:
58
59 if ( block == NULL )
60 {
61 method(0, data);
62 method(0, data);
63 method(0, data);
64 return;
65 }
66
67 sound = (SWFSoundInstance)block;
68 flags = sound->flags;
69
70 if ( sound->sound )
71 methodWriteUInt16(CHARACTERID(sound->sound), method, data);
72 else
73 methodWriteUInt16(0, method, data); /* 0 means NULL character */
74
75 method(flags, data);
76
77 if ( flags & SWF_SOUNDINFO_HASINPOINT )
78 methodWriteUInt32(sound->inPoint, method, data);
79
80 if ( flags & SWF_SOUNDINFO_HASOUTPOINT )
81 methodWriteUInt32(sound->outPoint, method, data);
82
83 if ( flags & SWF_SOUNDINFO_HASLOOPS )
84 methodWriteUInt16(sound->numLoops, method, data);
85
86 if ( flags & SWF_SOUNDINFO_HASENVELOPE )
87 {
88 method(sound->numEnvPoints, data);
89
90 for ( i=0; i<sound->numEnvPoints; ++i )
91 {
92 methodWriteUInt32((sound->envPoints[i]).mark44, method, data);
93 methodWriteUInt16((sound->envPoints[i]).level0, method, data);
94 methodWriteUInt16((sound->envPoints[i]).level1, method, data);
95 }
96 }
97 }
98
99
completeSWFSoundInstance(SWFBlock block)100 int completeSWFSoundInstance(SWFBlock block)
101 {
102 SWFSoundInstance sound;
103 byte flags;
104
105 // block may be null if we're calling from button.c:
106
107 if ( block == NULL )
108 return 3;
109
110 sound = (SWFSoundInstance)block;
111 flags = sound->flags;
112
113 return 3 /* (sound id + flags) */ +
114 ((flags & SWF_SOUNDINFO_HASINPOINT) ? 4 : 0) +
115 ((flags & SWF_SOUNDINFO_HASOUTPOINT) ? 4 : 0) +
116 ((flags & SWF_SOUNDINFO_HASLOOPS) ? 2 : 0) +
117 ((flags & SWF_SOUNDINFO_HASENVELOPE) ? (1 + 8*sound->numEnvPoints) : 0);
118 }
119
120 /*
121 * adds a SoundEnvelope to event sound
122 */
SWFSoundInstance_addEnvelope(SWFSoundInstance inst,unsigned int mark44,short left,short right)123 void SWFSoundInstance_addEnvelope(SWFSoundInstance inst,
124 unsigned int mark44 /* position in 44khz samples */,
125 short left /* volume left channel */,
126 short right /* volume right channel */)
127 {
128 inst->flags |= SWF_SOUNDINFO_HASENVELOPE;
129 inst->envPoints = (envPoint*) realloc(inst->envPoints,
130 (inst->numEnvPoints + 1) * sizeof(envPoint));
131 inst->envPoints[inst->numEnvPoints].mark44 = mark44;
132 inst->envPoints[inst->numEnvPoints].level0 = left;
133 inst->envPoints[inst->numEnvPoints].level1 = right;
134 inst->numEnvPoints++;
135 }
136
137 /*
138 * private constructor
139 * see SWFMove[Clip]_startSound()
140 */
newSWFSoundInstance(SWFSound sound)141 SWFSoundInstance newSWFSoundInstance(SWFSound sound)
142 {
143 SWFSoundInstance instance = (SWFSoundInstance)malloc(sizeof(struct SWFSoundInstance_s));
144 SWFBlock block = (SWFBlock)instance;
145
146 SWFBlockInit(block);
147
148 block->type = SWF_STARTSOUND;
149
150 block->writeBlock = writeSWFSoundInstanceToMethod;
151 block->complete = completeSWFSoundInstance;
152 /* block->dtor = destroySWFStartSoundBlock; */
153
154 instance->sound = sound;
155 instance->inPoint = 0;
156 instance->outPoint = 0;
157 instance->numLoops = 0;
158 instance->flags = 0;
159 instance->numEnvPoints = 0;
160 instance->envPoints = NULL;
161
162 return instance;
163 }
164
165 /*
166 * destroys a SWFSounInstance object
167 */
168 void
destroySWFSoundInstance(SWFSoundInstance soundInstance)169 destroySWFSoundInstance(SWFSoundInstance soundInstance)
170 {
171 destroySWFBlock((SWFBlock) soundInstance);
172 }
173
174
newSWFSoundInstance_stop(SWFSound sound)175 SWFSoundInstance newSWFSoundInstance_stop(SWFSound sound)
176 {
177 SWFSoundInstance instance = newSWFSoundInstance(sound);
178 instance->flags = SWF_SOUNDINFO_SYNCSTOPSOUND;
179 return instance;
180 }
181
newSWFSoundInstance_startNoMultiple(SWFSound sound)182 SWFSoundInstance newSWFSoundInstance_startNoMultiple(SWFSound sound)
183 {
184 SWFSoundInstance instance = newSWFSoundInstance(sound);
185 instance->flags = SWF_SOUNDINFO_SYNCNOMULTIPLE;
186 return instance;
187 }
188
189 /*
190 * don't start sound if already playing
191 */
SWFSoundInstance_setNoMultiple(SWFSoundInstance instance)192 void SWFSoundInstance_setNoMultiple(SWFSoundInstance instance)
193 {
194 instance->flags |= SWF_SOUNDINFO_SYNCNOMULTIPLE;
195 }
196
197 /*
198 * set loop start point
199 * Sets the loop start point counted in samples
200 */
SWFSoundInstance_setLoopInPoint(SWFSoundInstance instance,unsigned int point)201 void SWFSoundInstance_setLoopInPoint(SWFSoundInstance instance,
202 unsigned int point /* number of samples */)
203 {
204 instance->flags |= SWF_SOUNDINFO_HASINPOINT;
205 instance->inPoint = point;
206 }
207
208 /*
209 * set loop stop point
210 * Sets the loop's last sample to play
211 */
SWFSoundInstance_setLoopOutPoint(SWFSoundInstance instance,unsigned int point)212 void SWFSoundInstance_setLoopOutPoint(SWFSoundInstance instance,
213 unsigned int point /* number of samples */)
214 {
215 instance->flags |= SWF_SOUNDINFO_HASOUTPOINT;
216 instance->outPoint = point;
217 }
218
219 /*
220 * sets loop count
221 */
SWFSoundInstance_setLoopCount(SWFSoundInstance instance,int count)222 void SWFSoundInstance_setLoopCount(SWFSoundInstance instance, int count /* loop count */)
223 {
224 instance->flags |= SWF_SOUNDINFO_HASLOOPS;
225 instance->numLoops = count;
226 }
227
228 /*
229 * Local variables:
230 * tab-width: 2
231 * c-basic-offset: 2
232 * End:
233 */
234