blob: c55d2e814090459454eb7257d061da0afe7d1e07 [file] [log] [blame]
The Android Open Source Project7df30102009-03-03 19:30:38 -08001/*----------------------------------------------------------------------------
2 *
Dave Sparks56c99cd2009-08-24 17:35:45 -07003 * File:
The Android Open Source Project7df30102009-03-03 19:30:38 -08004 * eas_mdls.c
5 *
6 * Contents and purpose:
7 * This file contains DLS to EAS converter.
Dave Sparks56c99cd2009-08-24 17:35:45 -07008 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08009 * Copyright (c) 2005 Sonic Network Inc.
10
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 *----------------------------------------------------------------------------
24 * Revision Control:
25 * $Revision: 818 $
26 * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
27 *----------------------------------------------------------------------------
28*/
29
30/*
31 * NOTES:
32 *
33 * Processor Endian-ness:
34 *
35 * We use the EAS_HWGetDWord() and EAS_HWGetWord () functions
36 * extensively in this module. It would probably be faster to read
37 * an entire data structure, but this introduces the problem of
38 * sensitivity to processor endian-ness to the parser. By utlilizing
39 * the host wrapper functions, we avoid having to flip bytes around
40 * for big-endian processors. The default host wrapper versions of
41 * these functions are insensitive to processor endian-ness due to
42 * the fact that they read the file as a byte stream.
43 *
44 * Dynamic Memory:
45 *
46 * Dynamic memory allocation is a risky proposition in a mobile
47 * device. The memory can become fragmented, resulting in an
48 * inability to allocate a memory block, or garbage collection
49 * routines can use many CPU cycles. Either can contribute to
50 * failures of critical systems. Therefore, we try to minimize the
51 * number of memory allocations we make.
52 *
53 * We allocate a single large block of memory for the entire
54 * converted DLS collection, including the articulation data and
55 * samples. This block is then sub-allocated for the various
56 * data structures.
57 *
58 * Parser Overview:
59 *
60 * We make two passes through the file, the first pass to count the
61 * number of instruments, regions, etc. and allocate memory for
62 * them. The second pass parses the data into the allocated data
63 * structures.
64 *
65 * Conditional chunks are challenging in that they can occur
66 * anywhere in the list chunk that contains them. To simplify, we
67 * parse the blocks in a list in specific order, no matter which
68 * order they appear in the file. This way we don't allocate memory
69 * and parse a block that we end up throwing away later due to
70 * a conditional chunk.
71 *
72 * Assumptions that may bite us in the future:
73 *
74 * We make some assumptions to simplify things. The most fundamental
75 * assumption is that there will be no more than one of any type of
76 * chunk in a list. While this is consistent with the block diagram
77 * of the file layout in the mDLS spec, there is nothing in the
78 * spec that precludes having mulitple lar2 or rgn2 chunks, with
79 * conditional blocks that dictate their usage.
80 *
81 * DLS -> EAS Conversion Process:
82 *
83 * Another challenge is that the DLS structure does not map well to
84 * the current EAS sound library structure. Not all DLS constructs
85 * are supported, and data from DLS structures must sometimes be
86 * mapped to multiple EAS data structures. To simplify the process,
87 * the EAS region, articulation, and envelopes are treated as a
88 * single combined unit. Thus for each region, there must be one
89 * articulation element and two envelope elements.
90 *
91 * The sample processing is also a multi-step process. First the
92 * ptbl chunk is pre-parsed to determine the number of samples
93 * in the collection. The next step is to parse the instrument data
94 * to determine which samples are actually used by instruments.
95 * Some samples may not be used because they are used only in
96 * conditional blocks that the synthesizer cannot parse, or the
97 * author neglected to remove unused samples from the collection.
98 * In the next step, the active samples are read into memory and
99 * converted to the appropriate playback format. Finally, as the
100 * instruments are processed, the links are made to the samples and
101 * wsmp data is extracted for the region and articulation data
102 * structures.
103*/
104
105#ifndef _FILTER_ENABLED
106#error "Filter must be enabled if DLS_SYNTHESIZER is enabled"
107#endif
108
109/*------------------------------------
110 * includes
111 *------------------------------------
112*/
113
114/* this define allows us to use the sndlib.h structures as RW memory */
115#define SCNST
116
Wei Jiab01aa7d2017-02-07 10:35:31 -0800117#include "log/log.h"
118
The Android Open Source Project7df30102009-03-03 19:30:38 -0800119#include "eas_data.h"
120#include "eas_host.h"
121#include "eas_mdls.h"
122#include "eas_math.h"
123#include "dls.h"
124#include "dls2.h"
125#include "eas_report.h"
126
127//2 we should replace log10() function with fixed point routine in ConvertSampleRate()
128/* lint is choking on the ARM math.h file, so we declare the log10 function here */
129extern double log10(double x);
130
131/*------------------------------------
132 * defines
133 *------------------------------------
134*/
135
136// #define _DEBUG_DLS
137
Dave Sparks56c99cd2009-08-24 17:35:45 -0700138#define DLS_MAX_WAVE_COUNT 1024
139#define DLS_MAX_ART_COUNT 2048
140#define DLS_MAX_REGION_COUNT 2048
141#define DLS_MAX_INST_COUNT 256
142#define MAX_DLS_WAVE_SIZE (1024*1024)
The Android Open Source Project7df30102009-03-03 19:30:38 -0800143
Wei Jia59b38202015-08-20 16:03:14 -0700144#ifndef EAS_U32_MAX
145#define EAS_U32_MAX (4294967295U)
146#endif
147
148#ifndef EAS_I32_MAX
149#define EAS_I32_MAX (2147483647)
150#endif
151
The Android Open Source Project7df30102009-03-03 19:30:38 -0800152/*------------------------------------
153 * typedefs
154 *------------------------------------
155*/
156
157/* offsets to articulation data */
158typedef enum
159{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700160 PARAM_MODIFIED = 0,
161 PARAM_MOD_LFO_FREQ,
162 PARAM_MOD_LFO_DELAY,
The Android Open Source Project7df30102009-03-03 19:30:38 -0800163
Dave Sparks56c99cd2009-08-24 17:35:45 -0700164 PARAM_VIB_LFO_FREQ,
165 PARAM_VIB_LFO_DELAY,
The Android Open Source Project7df30102009-03-03 19:30:38 -0800166
Dave Sparks56c99cd2009-08-24 17:35:45 -0700167 PARAM_VOL_EG_DELAY,
168 PARAM_VOL_EG_ATTACK,
169 PARAM_VOL_EG_HOLD,
170 PARAM_VOL_EG_DECAY,
171 PARAM_VOL_EG_SUSTAIN,
172 PARAM_VOL_EG_RELEASE,
173 PARAM_VOL_EG_SHUTDOWN,
174 PARAM_VOL_EG_VEL_TO_ATTACK,
175 PARAM_VOL_EG_KEY_TO_DECAY,
176 PARAM_VOL_EG_KEY_TO_HOLD,
The Android Open Source Project7df30102009-03-03 19:30:38 -0800177
Dave Sparks56c99cd2009-08-24 17:35:45 -0700178 PARAM_MOD_EG_DELAY,
179 PARAM_MOD_EG_ATTACK,
180 PARAM_MOD_EG_HOLD,
181 PARAM_MOD_EG_DECAY,
182 PARAM_MOD_EG_SUSTAIN,
183 PARAM_MOD_EG_RELEASE,
184 PARAM_MOD_EG_VEL_TO_ATTACK,
185 PARAM_MOD_EG_KEY_TO_DECAY,
186 PARAM_MOD_EG_KEY_TO_HOLD,
The Android Open Source Project7df30102009-03-03 19:30:38 -0800187
Dave Sparks56c99cd2009-08-24 17:35:45 -0700188 PARAM_INITIAL_FC,
189 PARAM_INITIAL_Q,
190 PARAM_MOD_LFO_TO_FC,
191 PARAM_MOD_LFO_CC1_TO_FC,
192 PARAM_MOD_LFO_CHAN_PRESS_TO_FC,
193 PARAM_MOD_EG_TO_FC,
194 PARAM_VEL_TO_FC,
195 PARAM_KEYNUM_TO_FC,
The Android Open Source Project7df30102009-03-03 19:30:38 -0800196
Dave Sparks56c99cd2009-08-24 17:35:45 -0700197 PARAM_MOD_LFO_TO_GAIN,
198 PARAM_MOD_LFO_CC1_TO_GAIN,
199 PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN,
200 PARAM_VEL_TO_GAIN,
201
202 PARAM_TUNING,
203 PARAM_KEYNUM_TO_PITCH,
204 PARAM_VIB_LFO_TO_PITCH,
205 PARAM_VIB_LFO_CC1_TO_PITCH,
206 PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH,
207 PARAM_MOD_LFO_TO_PITCH,
208 PARAM_MOD_LFO_CC1_TO_PITCH,
209 PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH,
210 PARAM_MOD_EG_TO_PITCH,
211
212 PARAM_DEFAULT_PAN,
213 PARAM_MIDI_CC91_TO_REVERB_SEND,
214 PARAM_DEFAULT_REVERB_SEND,
215 PARAM_MIDI_CC93_TO_CHORUS_SEND,
216 PARAM_DEFAULT_CHORUS_SEND,
217 PARAM_TABLE_SIZE
The Android Open Source Project7df30102009-03-03 19:30:38 -0800218} E_ART_INDEX;
219
220/* temporary data structure combining region, articulation, and envelope data */
221typedef struct s_art_dls_tag
222{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700223 EAS_I16 values[PARAM_TABLE_SIZE];
The Android Open Source Project7df30102009-03-03 19:30:38 -0800224} S_DLS_ART_VALUES;
225
226/* temporary data structure for wlnk chunk data */
227typedef struct
228{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700229 EAS_I32 gain;
230 EAS_U32 loopStart;
231 EAS_U32 loopLength;
232 EAS_U32 sampleRate;
233 EAS_U16 bitsPerSample;
234 EAS_I16 fineTune;
235 EAS_U8 unityNote;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800236} S_WSMP_DATA;
237
238/* temporary data structure used while parsing a DLS file */
239typedef struct
240{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700241 S_DLS *pDLS;
242 EAS_HW_DATA_HANDLE hwInstData;
243 EAS_FILE_HANDLE fileHandle;
244 S_WSMP_DATA *wsmpData;
245 EAS_U32 instCount;
246 EAS_U32 regionCount;
247 EAS_U32 artCount;
248 EAS_U32 waveCount;
249 EAS_U32 wavePoolSize;
250 EAS_U32 wavePoolOffset;
251 EAS_BOOL bigEndian;
252 EAS_BOOL filterUsed;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800253} SDLS_SYNTHESIZER_DATA;
254
255/* connection lookup table */
256typedef struct s_connection_tag
257{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700258 EAS_U16 source;
259 EAS_U16 control;
260 EAS_U16 destination;
261 EAS_U16 connection;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800262} S_CONNECTION;
263
Dave Sparks56c99cd2009-08-24 17:35:45 -0700264static const S_CONNECTION connTable[] =
The Android Open Source Project7df30102009-03-03 19:30:38 -0800265{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700266 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ },
267 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY},
The Android Open Source Project7df30102009-03-03 19:30:38 -0800268
Dave Sparks56c99cd2009-08-24 17:35:45 -0700269 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ },
270 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY },
271
272 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY },
273 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK },
274 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD },
275 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY },
276 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN },
277 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE },
278 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN },
279 { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK },
280 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY },
281 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD },
282
283 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY },
284 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK },
285 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD },
286 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY },
287 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN },
288 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE },
289 { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK },
290 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY },
291 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD },
292
293 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC },
294 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q },
295 { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC },
296 { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC },
297 { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC },
298 { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC },
299 { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC },
300 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC },
301
302 { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN },
303 { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN },
304 { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN },
305 { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN },
306
307 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING },
308 { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH },
309 { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH },
310 { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH },
311 { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH },
312 { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH },
313 { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH },
314 { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH },
315 { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH },
316
317 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN },
318 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND },
319 { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND },
320 { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND },
321 { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800322};
323#define ENTRIES_IN_CONN_TABLE (sizeof(connTable)/sizeof(S_CONNECTION))
324
325static const S_DLS_ART_VALUES defaultArt =
326{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700327 0, /* not modified */
328 -851, /* Mod LFO frequency: 5 Hz */
329 -7973, /* Mod LFO delay: 10 milliseconds */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800330
Dave Sparks56c99cd2009-08-24 17:35:45 -0700331 -851, /* Vib LFO frequency: 5 Hz */
332 -7973, /* Vib LFO delay: 10 milliseconds */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800333
Dave Sparks56c99cd2009-08-24 17:35:45 -0700334 -32768, /* EG1 delay time: 0 secs */
335 -32768, /* EG1 attack time: 0 secs */
336 -32768, /* EG1 hold time: 0 secs */
337 -32768, /* EG1 decay time: 0 secs */
338 1000, /* EG1 sustain level: 100.0% */
339 -32768, /* EG1 release time: 0 secs */
340 -7271, /* EG1 shutdown time: 15 msecs */
341 0, /* EG1 velocity to attack: 0 time cents */
342 0, /* EG1 key number to decay: 0 time cents */
343 0, /* EG1 key number to hold: 0 time cents */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800344
Dave Sparks56c99cd2009-08-24 17:35:45 -0700345 -32768, /* EG2 delay time: 0 secs */
346 -32768, /* EG2 attack time: 0 secs */
347 -32768, /* EG2 hold time: 0 secs */
348 -32768, /* EG2 decay time: 0 secs */
349 1000, /* EG2 sustain level: 100.0% */
350 -32768, /* EG2 release time: 0 secs */
351 0, /* EG2 velocity to attack: 0 time cents */
352 0, /* EG2 key number to decay: 0 time cents */
353 0, /* EG2 key number to hold: 0 time cents */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800354
Dave Sparks56c99cd2009-08-24 17:35:45 -0700355 0x7fff, /* Initial Fc: Disabled */
356 0, /* Initial Q: 0 dB */
357 0, /* Mod LFO to Fc: 0 cents */
358 0, /* Mod LFO CC1 to Fc: 0 cents */
359 0, /* Mod LFO channel pressure to Fc: 0 cents */
360 0, /* EG2 to Fc: 0 cents */
361 0, /* Velocity to Fc: 0 cents */
362 0, /* Key number to Fc: 0 cents */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800363
Dave Sparks56c99cd2009-08-24 17:35:45 -0700364 0, /* Mod LFO to gain: 0 dB */
365 0, /* Mod LFO CC1 to gain: 0 dB */
366 0, /* Mod LFO channel pressure to gain: 0 dB */
367 960, /* Velocity to gain: 96 dB */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800368
Dave Sparks56c99cd2009-08-24 17:35:45 -0700369 0, /* Tuning: 0 cents */
370 12800, /* Key number to pitch: 12,800 cents */
371 0, /* Vibrato to pitch: 0 cents */
372 0, /* Vibrato CC1 to pitch: 0 cents */
373 0, /* Vibrato channel pressure to pitch: 0 cents */
374 0, /* Mod LFO to pitch: 0 cents */
375 0, /* Mod LFO CC1 to pitch: 0 cents */
376 0, /* Mod LFO channel pressure to pitch: 0 cents */
377 0, /* Mod EG to pitch: 0 cents */
378
379 0, /* Default pan: 0.0% */
380 0, /* Default reverb send: 0.0% */
381 1000, /* Default CC91 to reverb send: 100.0% */
382 0, /* Default chorus send: 0.0% */
383 1000 /* Default CC93 to chorus send: 100.0% */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800384};
385
386/*------------------------------------
387 * local variables
388 *------------------------------------
389*/
390
391#if defined(_8_BIT_SAMPLES)
392static const EAS_INT bitDepth = 8;
393#elif defined(_16_BIT_SAMPLES)
394static const EAS_INT bitDepth = 16;
395#else
396#error "Must define _8_BIT_SAMPLES or _16_BIT_SAMPLES"
397#endif
398
399static const EAS_U32 outputSampleRate = _OUTPUT_SAMPLE_RATE;
400static const EAS_I32 dlsRateConvert = DLS_RATE_CONVERT;
401static const EAS_I32 dlsLFOFrequencyConvert = DLS_LFO_FREQUENCY_CONVERT;
402
403/*------------------------------------
404 * inline functions
405 *------------------------------------
406*/
407EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset)
408{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700409 return (void*) (((EAS_U8*) p) + offset);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800410}
411
412/*------------------------------------
413 * prototypes
414 *------------------------------------
415*/
416static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize);
417static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wsmpPos, EAS_I32 wsmpSize);
418static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex);
419static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
420static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
Wei Jia40fc62b2015-08-21 13:41:42 -0700421static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *p, EAS_SAMPLE *pSample, EAS_U32 sampleLen);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800422static EAS_RESULT Parse_lins(SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
423static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
424static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale);
425static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions);
426static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex);
427static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn);
428static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt);
429static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt);
430static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex);
431static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue);
432static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp);
433static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex);
434static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate);
435static EAS_I16 ConvertSustain (EAS_I32 sustain);
436static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents);
437static EAS_I8 ConvertPan (EAS_I32 pan);
438static EAS_U8 ConvertQ (EAS_I32 q);
439
440#ifdef _DEBUG_DLS
441static void DumpDLS (S_EAS *pEAS);
442#endif
443
444
445/*----------------------------------------------------------------------------
446 * DLSParser ()
447 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700448 * Purpose:
449 *
450 * Inputs:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800451 * pEASData - pointer to over EAS data instance
452 * fileHandle - file handle for input file
453 * offset - offset into file where DLS data starts
Dave Sparks56c99cd2009-08-24 17:35:45 -0700454 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800455 * Outputs:
456 * EAS_RESULT
457 * ppEAS - address of pointer to alternate EAS wavetable
458 *
459 *----------------------------------------------------------------------------
460*/
461EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS)
462{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700463 EAS_RESULT result;
464 SDLS_SYNTHESIZER_DATA dls;
465 EAS_U32 temp;
466 EAS_I32 pos;
467 EAS_I32 chunkPos;
468 EAS_I32 size;
469 EAS_I32 instSize;
470 EAS_I32 rgnPoolSize;
471 EAS_I32 artPoolSize;
472 EAS_I32 waveLenSize;
473 EAS_I32 endDLS;
474 EAS_I32 wvplPos;
475 EAS_I32 wvplSize;
476 EAS_I32 linsPos;
477 EAS_I32 linsSize;
478 EAS_I32 ptblPos;
479 EAS_I32 ptblSize;
480 void *p;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800481
Dave Sparks56c99cd2009-08-24 17:35:45 -0700482 /* zero counts and pointers */
483 EAS_HWMemSet(&dls, 0, sizeof(dls));
The Android Open Source Project7df30102009-03-03 19:30:38 -0800484
Dave Sparks56c99cd2009-08-24 17:35:45 -0700485 /* save file handle and hwInstData to save copying pointers around */
486 dls.hwInstData = hwInstData;
487 dls.fileHandle = fileHandle;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800488
Dave Sparks56c99cd2009-08-24 17:35:45 -0700489 /* NULL return value in case of error */
490 *ppDLS = NULL;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800491
Dave Sparks56c99cd2009-08-24 17:35:45 -0700492 /* seek to start of DLS and read in RIFF tag and set processor endian flag */
493 if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS)
494 return result;
495 if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS)
496 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800497
Dave Sparks56c99cd2009-08-24 17:35:45 -0700498 /* check for processor endian-ness */
499 dls.bigEndian = (temp == CHUNK_RIFF);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800500
Dave Sparks56c99cd2009-08-24 17:35:45 -0700501 /* first chunk should be DLS */
502 pos = offset;
503 if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
504 return result;
505 if (temp != CHUNK_DLS)
506 {
507 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ }
508 return EAS_ERROR_FILE_FORMAT;
509 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800510
Dave Sparks56c99cd2009-08-24 17:35:45 -0700511 /* no instrument or wavepool chunks */
512 linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800513
Dave Sparks56c99cd2009-08-24 17:35:45 -0700514 /* scan the chunks in the DLS list */
515 endDLS = offset + size;
516 pos = offset + 12;
517 while (pos < endDLS)
518 {
519 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800520
Dave Sparks56c99cd2009-08-24 17:35:45 -0700521 /* get the next chunk type */
522 if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
523 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800524
Dave Sparks56c99cd2009-08-24 17:35:45 -0700525 /* parse useful chunks */
526 switch (temp)
527 {
528 case CHUNK_CDL:
529 if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS)
530 return result;
531 if (!temp)
532 return EAS_ERROR_UNRECOGNIZED_FORMAT;
533 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800534
Dave Sparks56c99cd2009-08-24 17:35:45 -0700535 case CHUNK_LINS:
536 linsPos = chunkPos + 12;
537 linsSize = size - 4;
538 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800539
Dave Sparks56c99cd2009-08-24 17:35:45 -0700540 case CHUNK_WVPL:
541 wvplPos = chunkPos + 12;
542 wvplSize = size - 4;
543 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800544
Dave Sparks56c99cd2009-08-24 17:35:45 -0700545 case CHUNK_PTBL:
546 ptblPos = chunkPos + 8;
547 ptblSize = size - 4;
548 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800549
Dave Sparks56c99cd2009-08-24 17:35:45 -0700550 default:
551 break;
552 }
553 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800554
Dave Sparks56c99cd2009-08-24 17:35:45 -0700555 /* must have a lins chunk */
556 if (linsSize == 0)
557 {
558 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ }
559 return EAS_ERROR_UNRECOGNIZED_FORMAT;
560 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800561
Dave Sparks56c99cd2009-08-24 17:35:45 -0700562 /* must have a wvpl chunk */
563 if (wvplSize == 0)
564 {
565 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ }
566 return EAS_ERROR_UNRECOGNIZED_FORMAT;
567 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800568
Dave Sparks56c99cd2009-08-24 17:35:45 -0700569 /* must have a ptbl chunk */
570 if ((ptblSize == 0) || (ptblSize > DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))
571 {
572 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ }
573 return EAS_ERROR_UNRECOGNIZED_FORMAT;
574 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800575
Dave Sparks56c99cd2009-08-24 17:35:45 -0700576 /* pre-parse the wave pool chunk */
577 if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS)
578 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800579
Dave Sparks56c99cd2009-08-24 17:35:45 -0700580 /* limit check */
581 if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT))
582 {
583 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ }
584 return EAS_ERROR_FILE_FORMAT;
585 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800586
Dave Sparks56c99cd2009-08-24 17:35:45 -0700587 /* allocate memory for wsmp data */
588 dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
589 if (dls.wsmpData == NULL)
590 {
591 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ }
592 return EAS_ERROR_MALLOC_FAILED;
593 }
594 EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
The Android Open Source Project7df30102009-03-03 19:30:38 -0800595
Dave Sparks56c99cd2009-08-24 17:35:45 -0700596 /* pre-parse the lins chunk */
597 result = Parse_lins(&dls, linsPos, linsSize);
598 if (result == EAS_SUCCESS)
599 {
The Android Open Source Project7df30102009-03-03 19:30:38 -0800600
Dave Sparks56c99cd2009-08-24 17:35:45 -0700601 /* limit check */
602 if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT))
603 {
604 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ }
605 return EAS_ERROR_FILE_FORMAT;
606 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800607
Amit Shekharb2545582013-03-20 14:51:24 -0700608 /* limit check - warn user if artCount is 0 and use default articulations */
609 if ( dls.artCount == 0 )
610 {
611 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS file contains 0 #articulations, using default.\n"); */ }
612 }
613
614 /* limit check */
615 if ( dls.artCount > DLS_MAX_ART_COUNT )
Dave Sparks56c99cd2009-08-24 17:35:45 -0700616 {
617 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ }
618 return EAS_ERROR_FILE_FORMAT;
619 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800620
Dave Sparks56c99cd2009-08-24 17:35:45 -0700621 /* limit check */
622 if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT))
623 {
624 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ }
625 return EAS_ERROR_FILE_FORMAT;
626 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800627
Dave Sparks56c99cd2009-08-24 17:35:45 -0700628 /* Allocate memory for the converted DLS data */
629 /* calculate size of instrument data */
630 instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800631
Dave Sparks56c99cd2009-08-24 17:35:45 -0700632 /* calculate size of region pool */
633 rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800634
Dave Sparks56c99cd2009-08-24 17:35:45 -0700635 /* calculate size of articulation pool, add one for default articulation */
636 dls.artCount++;
637 artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800638
Dave Sparks56c99cd2009-08-24 17:35:45 -0700639 /* calculate size of wave length and offset arrays */
640 waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32));
The Android Open Source Project7df30102009-03-03 19:30:38 -0800641
Dave Sparks56c99cd2009-08-24 17:35:45 -0700642 /* calculate final memory size */
643 size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize;
644 if (size <= 0) {
645 return EAS_ERROR_FILE_FORMAT;
646 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800647
Dave Sparks56c99cd2009-08-24 17:35:45 -0700648 /* allocate the main EAS chunk */
649 dls.pDLS = EAS_HWMalloc(dls.hwInstData, size);
650 if (dls.pDLS == NULL)
651 {
652 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ }
653 return EAS_ERROR_MALLOC_FAILED;
654 }
655 EAS_HWMemSet(dls.pDLS, 0, size);
656 dls.pDLS->refCount = 1;
657 p = PtrOfs(dls.pDLS, sizeof(S_EAS));
The Android Open Source Project7df30102009-03-03 19:30:38 -0800658
Dave Sparks56c99cd2009-08-24 17:35:45 -0700659 /* setup pointer to programs */
660 dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount;
661 dls.pDLS->pDLSPrograms = p;
662 p = PtrOfs(p, instSize);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800663
Dave Sparks56c99cd2009-08-24 17:35:45 -0700664 /* setup pointer to regions */
665 dls.pDLS->pDLSRegions = p;
666 dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount;
667 p = PtrOfs(p, rgnPoolSize);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800668
Dave Sparks56c99cd2009-08-24 17:35:45 -0700669 /* setup pointer to articulations */
670 dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount;
671 dls.pDLS->pDLSArticulations = p;
672 p = PtrOfs(p, artPoolSize);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800673
Dave Sparks56c99cd2009-08-24 17:35:45 -0700674 /* setup pointer to wave length table */
675 dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount;
676 dls.pDLS->pDLSSampleLen = p;
677 p = PtrOfs(p, waveLenSize);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800678
Dave Sparks56c99cd2009-08-24 17:35:45 -0700679 /* setup pointer to wave offsets table */
680 dls.pDLS->pDLSSampleOffsets = p;
681 p = PtrOfs(p, waveLenSize);
682
683 /* setup pointer to wave pool */
684 dls.pDLS->pDLSSamples = p;
685
686 /* clear filter flag */
687 dls.filterUsed = EAS_FALSE;
688
689 /* parse the wave pool and load samples */
690 result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize);
691 }
692
693 /* create the default articulation */
jerond34f9112016-08-17 15:18:48 +0800694 if (dls.pDLS) {
695 Convert_art(&dls, &defaultArt, 0);
696 dls.artCount = 1;
697 }
Dave Sparks56c99cd2009-08-24 17:35:45 -0700698 /* parse the lins chunk and load instruments */
699 dls.regionCount = dls.instCount = 0;
700 if (result == EAS_SUCCESS)
701 result = Parse_lins(&dls, linsPos, linsSize);
702
703 /* clean up any temporary objects that were allocated */
704 if (dls.wsmpData)
705 EAS_HWFree(dls.hwInstData, dls.wsmpData);
706
707 /* if successful, return a pointer to the EAS collection */
708 if (result == EAS_SUCCESS)
709 {
710 *ppDLS = dls.pDLS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800711#ifdef _DEBUG_DLS
Dave Sparks56c99cd2009-08-24 17:35:45 -0700712 DumpDLS(dls.pDLS);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800713#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -0700714 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800715
Dave Sparks56c99cd2009-08-24 17:35:45 -0700716 /* something went wrong, deallocate the EAS collection */
717 else
718 DLSCleanup(dls.hwInstData, dls.pDLS);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800719
Dave Sparks56c99cd2009-08-24 17:35:45 -0700720 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800721}
722
723/*----------------------------------------------------------------------------
724 * DLSCleanup ()
725 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700726 * Purpose:
727 *
728 * Inputs:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800729 * pEASData - pointer to over EAS data instance
730 * pEAS - pointer to alternate EAS wavetable
Dave Sparks56c99cd2009-08-24 17:35:45 -0700731 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800732 * Outputs:
733 * EAS_RESULT
734 *
735 *----------------------------------------------------------------------------
736*/
737EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS)
738{
739
Dave Sparks56c99cd2009-08-24 17:35:45 -0700740 /* free the allocated memory */
741 if (pDLS)
742 {
743 if (pDLS->refCount)
744 {
745 if (--pDLS->refCount == 0)
746 EAS_HWFree(hwInstData, pDLS);
747 }
748 }
749 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800750}
751
752/*----------------------------------------------------------------------------
753 * DLSAddRef ()
754 *----------------------------------------------------------------------------
755 * Increment reference count
756 *----------------------------------------------------------------------------
757*/
758void DLSAddRef (S_DLS *pDLS)
759{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700760 if (pDLS)
761 pDLS->refCount++;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800762}
763
764/*----------------------------------------------------------------------------
765 * NextChunk ()
766 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700767 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800768 * Returns the type and size of the next chunk in the file
769 *
Dave Sparks56c99cd2009-08-24 17:35:45 -0700770 * Inputs:
771 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800772 * Outputs:
773 *
774 * Side Effects:
775 *----------------------------------------------------------------------------
776*/
777static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize)
778{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700779 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800780
Dave Sparks56c99cd2009-08-24 17:35:45 -0700781 /* seek to start of chunk */
782 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS)
783 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800784
Dave Sparks56c99cd2009-08-24 17:35:45 -0700785 /* read the chunk type */
786 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
787 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800788
Dave Sparks56c99cd2009-08-24 17:35:45 -0700789 /* read the chunk size */
790 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS)
791 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800792
Dave Sparks56c99cd2009-08-24 17:35:45 -0700793 /* get form type for RIFF and LIST types */
794 if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST))
795 {
The Android Open Source Project7df30102009-03-03 19:30:38 -0800796
Dave Sparks56c99cd2009-08-24 17:35:45 -0700797 /* read the form type */
798 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
799 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800800
Dave Sparks56c99cd2009-08-24 17:35:45 -0700801 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800802
Dave Sparks56c99cd2009-08-24 17:35:45 -0700803 /* calculate start of next chunk */
804 *pPos += *pSize + 8;
805
806 /* adjust to word boundary */
807 if (*pPos & 1)
808 (*pPos)++;
809
810 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800811}
812
813/*----------------------------------------------------------------------------
814 * Parse_ptbl ()
815 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700816 * Purpose:
817 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800818 *
819 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700820 *
821 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800822 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700823 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800824 *
825 *----------------------------------------------------------------------------
826*/
827static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize)
828{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700829 EAS_RESULT result;
830 EAS_U32 temp;
831 EAS_FILE_HANDLE tempFile;
832 EAS_U16 waveIndex;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800833
Dave Sparks56c99cd2009-08-24 17:35:45 -0700834 /* seek to start of chunk */
835 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
836 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800837
Dave Sparks56c99cd2009-08-24 17:35:45 -0700838 /* get the structure size */
839 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
840 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800841
Dave Sparks56c99cd2009-08-24 17:35:45 -0700842 /* get the number of waves */
843 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
844 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800845
846#if 0
Dave Sparks56c99cd2009-08-24 17:35:45 -0700847 /* just need the wave count on the first pass */
848 if (!pDLSData->pDLS)
849 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800850#endif
851
Dave Sparks56c99cd2009-08-24 17:35:45 -0700852 /* open duplicate file handle */
853 if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
854 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800855
Dave Sparks56c99cd2009-08-24 17:35:45 -0700856 /* read to end of chunk */
857 for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
858 {
The Android Open Source Project7df30102009-03-03 19:30:38 -0800859
Dave Sparks56c99cd2009-08-24 17:35:45 -0700860 /* get the offset to the wave and make sure it is within the wtbl chunk */
861 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
862 return result;
863 if (temp > (EAS_U32) wtblSize)
864 {
865 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
866 EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
867 return EAS_ERROR_FILE_FORMAT;
868 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800869
Dave Sparks56c99cd2009-08-24 17:35:45 -0700870 /* parse the wave */
871 if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32) temp, waveIndex)) != EAS_SUCCESS)
872 return result;
873 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800874
Dave Sparks56c99cd2009-08-24 17:35:45 -0700875 /* close the temporary handle and return */
876 EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
877 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800878}
879
880/*----------------------------------------------------------------------------
881 * Parse_wave ()
882 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700883 * Purpose:
884 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800885 *
886 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700887 *
888 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800889 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700890 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800891 *
892 *----------------------------------------------------------------------------
893*/
894static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex)
895{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700896 EAS_RESULT result;
897 EAS_U32 temp;
898 EAS_I32 size;
899 EAS_I32 endChunk;
900 EAS_I32 chunkPos;
901 EAS_I32 wsmpPos = 0;
902 EAS_I32 fmtPos = 0;
903 EAS_I32 dataPos = 0;
904 EAS_I32 dataSize = 0;
905 S_WSMP_DATA *p;
906 void *pSample;
907 S_WSMP_DATA wsmp;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800908
Dave Sparks56c99cd2009-08-24 17:35:45 -0700909 /* seek to start of chunk */
910 chunkPos = pos + 12;
911 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
912 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800913
Dave Sparks56c99cd2009-08-24 17:35:45 -0700914 /* get the chunk type */
915 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
916 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800917
Dave Sparks56c99cd2009-08-24 17:35:45 -0700918 /* make sure it is a wave chunk */
919 if (temp != CHUNK_WAVE)
920 {
921 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ }
922 return EAS_ERROR_FILE_FORMAT;
923 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800924
Dave Sparks56c99cd2009-08-24 17:35:45 -0700925 /* read to end of chunk */
926 pos = chunkPos;
927 endChunk = pos + size;
928 while (pos < endChunk)
929 {
930 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800931
Dave Sparks56c99cd2009-08-24 17:35:45 -0700932 /* get the chunk type */
933 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
934 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800935
Dave Sparks56c99cd2009-08-24 17:35:45 -0700936 /* parse useful chunks */
937 switch (temp)
938 {
939 case CHUNK_WSMP:
940 wsmpPos = chunkPos + 8;
941 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800942
Dave Sparks56c99cd2009-08-24 17:35:45 -0700943 case CHUNK_FMT:
944 fmtPos = chunkPos + 8;
945 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800946
Dave Sparks56c99cd2009-08-24 17:35:45 -0700947 case CHUNK_DATA:
948 dataPos = chunkPos + 8;
949 dataSize = size;
950 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800951
Dave Sparks56c99cd2009-08-24 17:35:45 -0700952 default:
953 break;
954 }
955 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800956
Dave Sparks56c99cd2009-08-24 17:35:45 -0700957 // limit to reasonable size
Eric Laurente90223d2015-05-14 09:10:40 -0700958 if (dataSize < 0 || dataSize > MAX_DLS_WAVE_SIZE)
Dave Sparks56c99cd2009-08-24 17:35:45 -0700959 {
960 return EAS_ERROR_SOUND_LIBRARY;
961 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800962
Dave Sparks56c99cd2009-08-24 17:35:45 -0700963 /* for first pass, use temporary variable */
964 if (pDLSData->pDLS == NULL)
965 p = &wsmp;
966 else
967 p = &pDLSData->wsmpData[waveIndex];
The Android Open Source Project7df30102009-03-03 19:30:38 -0800968
Dave Sparks56c99cd2009-08-24 17:35:45 -0700969 /* set the defaults */
970 p->fineTune = 0;
971 p->unityNote = 60;
972 p->gain = 0;
973 p->loopStart = 0;
974 p->loopLength = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800975
Dave Sparks56c99cd2009-08-24 17:35:45 -0700976 /* must have a fmt chunk */
977 if (!fmtPos)
978 {
979 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ }
980 return EAS_ERROR_UNRECOGNIZED_FORMAT;
981 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800982
Dave Sparks56c99cd2009-08-24 17:35:45 -0700983 /* must have a data chunk */
984 if (!dataPos)
985 {
986 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ }
987 return EAS_ERROR_UNRECOGNIZED_FORMAT;
988 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800989
Dave Sparks56c99cd2009-08-24 17:35:45 -0700990 /* parse the wsmp chunk */
991 if (wsmpPos)
992 {
993 if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS)
994 return result;
995 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800996
Dave Sparks56c99cd2009-08-24 17:35:45 -0700997 /* parse the fmt chunk */
998 if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS)
999 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001000
Dave Sparks56c99cd2009-08-24 17:35:45 -07001001 /* calculate the size of the wavetable needed. We need only half
1002 * the memory for 16-bit samples when in 8-bit mode, and we need
1003 * double the memory for 8-bit samples in 16-bit mode. For
1004 * unlooped samples, we may use ADPCM. If so, we need only 1/4
1005 * the memory.
1006 *
1007 * We also need to add one for looped samples to allow for
1008 * the first sample to be copied to the end of the loop.
1009 */
The Android Open Source Project7df30102009-03-03 19:30:38 -08001010
Dave Sparks56c99cd2009-08-24 17:35:45 -07001011 /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */
1012 /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */
1013 if (bitDepth == 8)
1014 {
1015 if (p->bitsPerSample == 8)
1016 size = dataSize;
1017 else
1018 /*lint -e{704} use shift for performance */
1019 size = dataSize >> 1;
1020 if (p->loopLength)
1021 size++;
1022 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001023
Dave Sparks56c99cd2009-08-24 17:35:45 -07001024 else
1025 {
1026 if (p->bitsPerSample == 16)
1027 size = dataSize;
1028 else
1029 /*lint -e{703} use shift for performance */
1030 size = dataSize << 1;
1031 if (p->loopLength)
1032 size += 2;
1033 }
1034
1035 /* for first pass, add size to wave pool size and return */
1036 if (pDLSData->pDLS == NULL)
1037 {
1038 pDLSData->wavePoolSize += (EAS_U32) size;
1039 return EAS_SUCCESS;
1040 }
1041
1042 /* allocate memory and read in the sample data */
Wei Jia40fc62b2015-08-21 13:41:42 -07001043 pSample = (EAS_U8*)pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset;
Dave Sparks56c99cd2009-08-24 17:35:45 -07001044 pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset;
1045 pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size;
1046 pDLSData->wavePoolOffset += (EAS_U32) size;
1047 if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize)
1048 {
1049 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ }
1050 return EAS_ERROR_SOUND_LIBRARY;
1051 }
1052
Wei Jia40fc62b2015-08-21 13:41:42 -07001053 if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample, (EAS_U32)size)) != EAS_SUCCESS)
Dave Sparks56c99cd2009-08-24 17:35:45 -07001054 return result;
1055
1056 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001057}
1058
1059/*----------------------------------------------------------------------------
1060 * Parse_wsmp ()
1061 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001062 * Purpose:
1063 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001064 *
1065 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001066 *
1067 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001068 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001069 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001070 *
1071 *----------------------------------------------------------------------------
1072*/
1073static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
1074{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001075 EAS_RESULT result;
1076 EAS_U16 wtemp;
1077 EAS_U32 ltemp;
1078 EAS_U32 cbSize;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001079
Dave Sparks56c99cd2009-08-24 17:35:45 -07001080 /* seek to start of chunk */
1081 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1082 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001083
Dave Sparks56c99cd2009-08-24 17:35:45 -07001084 /* get structure size */
1085 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
1086 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001087
Dave Sparks56c99cd2009-08-24 17:35:45 -07001088 /* get unity note */
1089 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1090 return result;
1091 if (wtemp <= 127)
1092 p->unityNote = (EAS_U8) wtemp;
1093 else
1094 {
1095 p->unityNote = 60;
1096 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
1097 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001098
Dave Sparks56c99cd2009-08-24 17:35:45 -07001099 /* get fine tune */
1100 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
1101 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001102
Dave Sparks56c99cd2009-08-24 17:35:45 -07001103 /* get gain */
1104 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
1105 return result;
1106 if (p->gain > 0)
1107 {
1108 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
1109 p->gain = 0;
1110 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001111
Dave Sparks56c99cd2009-08-24 17:35:45 -07001112 /* option flags */
1113 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1114 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001115
Dave Sparks56c99cd2009-08-24 17:35:45 -07001116 /* sample loops */
1117 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1118 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001119
Dave Sparks56c99cd2009-08-24 17:35:45 -07001120 /* if looped sample, get loop data */
1121 if (ltemp)
1122 {
The Android Open Source Project7df30102009-03-03 19:30:38 -08001123
Dave Sparks56c99cd2009-08-24 17:35:45 -07001124 if (ltemp > 1)
1125 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }
1126
1127 /* skip ahead to loop data */
1128 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
1129 return result;
1130
1131 /* get structure size */
1132 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1133 return result;
1134
1135 /* get loop type */
1136 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1137 return result;
1138
1139 /* get loop start */
1140 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
1141 return result;
1142
1143 /* get loop length */
1144 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
1145 return result;
Wei Jia59b38202015-08-20 16:03:14 -07001146
1147 /* ensure no overflow */
1148 if (p->loopLength
1149 && ((p->loopStart > EAS_U32_MAX - p->loopLength)
1150 || (p->loopStart + p->loopLength > EAS_U32_MAX / sizeof(EAS_SAMPLE))))
1151 {
1152 return EAS_FAILURE;
1153 }
Dave Sparks56c99cd2009-08-24 17:35:45 -07001154 }
1155
1156 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001157}
1158
1159/*----------------------------------------------------------------------------
1160 * Parse_fmt ()
1161 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001162 * Purpose:
1163 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001164 *
1165 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001166 *
1167 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001168 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001169 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001170 *
1171 *----------------------------------------------------------------------------
1172*/
1173static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
1174{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001175 EAS_RESULT result;
1176 EAS_U16 wtemp;
1177 EAS_U32 ltemp;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001178
Dave Sparks56c99cd2009-08-24 17:35:45 -07001179 /* seek to start of chunk */
1180 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1181 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001182
Dave Sparks56c99cd2009-08-24 17:35:45 -07001183 /* get format tag */
1184 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1185 return result;
1186 if (wtemp != WAVE_FORMAT_PCM)
1187 {
1188 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
1189 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1190 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001191
Dave Sparks56c99cd2009-08-24 17:35:45 -07001192 /* get number of channels */
1193 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1194 return result;
1195 if (wtemp != 1)
1196 {
1197 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
1198 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1199 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001200
Dave Sparks56c99cd2009-08-24 17:35:45 -07001201 /* get sample rate */
1202 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
1203 return result;
1204
1205 /* bytes/sec */
1206 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1207 return result;
1208
1209 /* block align */
1210 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1211 return result;
1212
1213 /* bits/sample */
1214 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
1215 return result;
1216
1217 if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
1218 {
1219 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
1220 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1221 }
1222
1223 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001224}
1225
1226#if defined( _8_BIT_SAMPLES)
1227/*----------------------------------------------------------------------------
1228 * Parse_data ()
1229 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001230 * Purpose:
1231 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001232 * NOTE: The optimized assembly versions of the interpolator require
1233 * an extra sample at the end of the loop - a copy of the first
1234 * sample. This routine must allocate an extra sample of data and
1235 * copy the first sample of the loop to the end.
1236 *
1237 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001238 *
1239 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001240 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001241 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001242 *
1243 *----------------------------------------------------------------------------
1244*/
Wei Jia40fc62b2015-08-21 13:41:42 -07001245static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample, EAS_U32 sampleLen)
The Android Open Source Project7df30102009-03-03 19:30:38 -08001246{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001247 EAS_RESULT result;
1248 EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
1249 EAS_I32 count;
1250 EAS_I32 i;
1251 EAS_I8 *p;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001252
Dave Sparks56c99cd2009-08-24 17:35:45 -07001253 /* seek to start of chunk */
1254 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1255 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001256
Dave Sparks56c99cd2009-08-24 17:35:45 -07001257 /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
1258 p = pSample;
1259 if (pWsmp->bitsPerSample == 8)
1260 {
1261 if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
1262 return result;
1263 for (i = 0; i < size; i++)
1264 /*lint -e{734} convert from unsigned to signed audio */
1265 *p++ ^= 0x80;
1266 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001267
Dave Sparks56c99cd2009-08-24 17:35:45 -07001268 /* 16-bit samples, need to convert to 8-bit or ADPCM */
1269 else
1270 {
The Android Open Source Project7df30102009-03-03 19:30:38 -08001271
Dave Sparks56c99cd2009-08-24 17:35:45 -07001272 while (size)
1273 {
1274 EAS_I8 *pInput;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001275
Dave Sparks56c99cd2009-08-24 17:35:45 -07001276 /* for undithered conversion, we're just copying the 8-bit data */
1277 if (pDLSData->bigEndian)
1278 pInput = (EAS_I8*) convBuf;
1279 else
1280 pInput = (EAS_I8*) convBuf + 1;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001281
Dave Sparks56c99cd2009-08-24 17:35:45 -07001282 /* read a small chunk of data and convert it */
1283 count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
1284 if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
1285 return result;
1286 size -= count;
1287 /*lint -e{704} use shift for performance */
1288 count = count >> 1;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001289
Dave Sparks56c99cd2009-08-24 17:35:45 -07001290 while (count--)
1291 {
1292 *p++ = *pInput;
1293 pInput += 2;
1294 }
1295 }
1296 }
1297
1298 /* for looped samples, copy the last sample to the end */
1299 if (pWsmp->loopLength)
Wei Jia59b38202015-08-20 16:03:14 -07001300 {
Wei Jia40fc62b2015-08-21 13:41:42 -07001301 if (sampleLen < sizeof(EAS_SAMPLE)
1302 || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE))
Wei Jia59b38202015-08-20 16:03:14 -07001303 {
1304 return EAS_FAILURE;
1305 }
1306
Dave Sparks56c99cd2009-08-24 17:35:45 -07001307 pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];
Wei Jia59b38202015-08-20 16:03:14 -07001308 }
Dave Sparks56c99cd2009-08-24 17:35:45 -07001309
1310 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001311}
1312#elif defined(_16_BIT_SAMPLES)
1313#error "16-bit DLS conversion not implemented yet"
1314#else
1315#error "Must specifiy _8_BIT_SAMPLES or _16_BIT_SAMPLES"
1316#endif
1317
1318/*----------------------------------------------------------------------------
1319 * Parse_lins ()
1320 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001321 * Purpose:
1322 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001323 *
1324 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001325 *
1326 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001327 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001328 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001329 *
1330 *----------------------------------------------------------------------------
1331*/
1332static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
1333{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001334 EAS_RESULT result;
1335 EAS_U32 temp;
1336 EAS_I32 endChunk;
1337 EAS_I32 chunkPos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001338
Dave Sparks56c99cd2009-08-24 17:35:45 -07001339 /* seek to start of chunk */
1340 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1341 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001342
Dave Sparks56c99cd2009-08-24 17:35:45 -07001343 /* read to end of chunk */
1344 endChunk = pos + size;
1345 while (pos < endChunk)
1346 {
1347 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001348
Dave Sparks56c99cd2009-08-24 17:35:45 -07001349 /* get the next chunk type */
1350 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1351 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001352
Dave Sparks56c99cd2009-08-24 17:35:45 -07001353 /* only instrument chunks are useful */
1354 if (temp != CHUNK_INS)
1355 continue;
1356
1357 if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
1358 return result;
1359 }
1360
1361 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001362}
1363
1364/*----------------------------------------------------------------------------
1365 * Parse_ins ()
1366 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001367 * Purpose:
1368 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001369 *
1370 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001371 *
1372 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001373 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001374 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001375 *
1376 *----------------------------------------------------------------------------
1377*/
1378static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
1379{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001380 EAS_RESULT result;
1381 EAS_U32 temp;
1382 EAS_I32 chunkPos;
1383 EAS_I32 endChunk;
1384 EAS_I32 lrgnPos;
1385 EAS_I32 lrgnSize;
1386 EAS_I32 lartPos;
1387 EAS_I32 lartSize;
1388 EAS_I32 lar2Pos;
1389 EAS_I32 lar2Size;
1390 EAS_I32 inshPos;
1391 EAS_U32 regionCount;
1392 EAS_U32 locale;
1393 S_DLS_ART_VALUES art;
1394 S_PROGRAM *pProgram;
1395 EAS_U16 artIndex;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001396
Dave Sparks56c99cd2009-08-24 17:35:45 -07001397 /* seek to start of chunk */
1398 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1399 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001400
Dave Sparks56c99cd2009-08-24 17:35:45 -07001401 /* no chunks yet */
1402 lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001403
Dave Sparks56c99cd2009-08-24 17:35:45 -07001404 /* read to end of chunk */
1405 endChunk = pos + size;
1406 while (pos < endChunk)
1407 {
1408 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001409
Dave Sparks56c99cd2009-08-24 17:35:45 -07001410 /* get the next chunk type */
1411 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1412 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001413
Dave Sparks56c99cd2009-08-24 17:35:45 -07001414 /* parse useful chunks */
1415 switch (temp)
1416 {
1417 case CHUNK_INSH:
1418 inshPos = chunkPos + 8;
1419 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001420
Dave Sparks56c99cd2009-08-24 17:35:45 -07001421 case CHUNK_LART:
1422 lartPos = chunkPos + 12;
1423 lartSize = size;
1424 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001425
Dave Sparks56c99cd2009-08-24 17:35:45 -07001426 case CHUNK_LAR2:
1427 lar2Pos = chunkPos + 12;
1428 lar2Size = size;
1429 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001430
Dave Sparks56c99cd2009-08-24 17:35:45 -07001431 case CHUNK_LRGN:
1432 lrgnPos = chunkPos + 12;
1433 lrgnSize = size;
1434 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001435
Dave Sparks56c99cd2009-08-24 17:35:45 -07001436 default:
1437 break;
1438 }
1439 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001440
Dave Sparks56c99cd2009-08-24 17:35:45 -07001441 /* must have an lrgn to be useful */
1442 if (!lrgnPos)
1443 {
1444 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
1445 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1446 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001447
Dave Sparks56c99cd2009-08-24 17:35:45 -07001448 /* must have an insh to be useful */
1449 if (!inshPos)
1450 {
1451 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
1452 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1453 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001454
Dave Sparks56c99cd2009-08-24 17:35:45 -07001455 /* parse the instrument header */
1456 if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
1457 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001458
Dave Sparks56c99cd2009-08-24 17:35:45 -07001459 /* initialize and parse the global data first */
1460 EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
1461 if (lartPos)
1462 if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
1463 return result;
1464 if (lar2Pos)
1465 if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
1466 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001467
Dave Sparks56c99cd2009-08-24 17:35:45 -07001468 if (art.values[PARAM_MODIFIED])
1469 {
1470 artIndex = (EAS_U16) pDLSData->artCount;
1471 pDLSData->artCount++;
1472 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001473
Dave Sparks56c99cd2009-08-24 17:35:45 -07001474 /* convert data on second pass */
1475 if (pDLSData->pDLS)
1476 {
1477
1478 if (art.values[PARAM_MODIFIED])
1479 Convert_art(pDLSData, &art, artIndex);
1480
1481 /* setup pointers */
1482 pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];
1483
1484 /* initialize instrument */
1485 pProgram->locale = locale;
1486 pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;
1487
1488 }
1489
1490 /* parse the region data */
1491 if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
1492 return result;
1493
1494 /* bump instrument count */
1495 pDLSData->instCount++;
1496 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001497}
1498
1499/*----------------------------------------------------------------------------
1500 * Parse_insh ()
1501 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001502 * Purpose:
1503 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001504 *
1505 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001506 *
1507 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001508 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001509 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001510 *
1511 *----------------------------------------------------------------------------
1512*/
1513static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale)
1514{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001515 EAS_RESULT result;
1516 EAS_U32 bank;
1517 EAS_U32 program;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001518
Dave Sparks56c99cd2009-08-24 17:35:45 -07001519 /* seek to start of chunk */
1520 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1521 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001522
Dave Sparks56c99cd2009-08-24 17:35:45 -07001523 /* get the region count and locale */
1524 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
1525 return result;
1526 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
1527 return result;
1528 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
1529 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001530
Dave Sparks56c99cd2009-08-24 17:35:45 -07001531 /* verify the parameters are valid */
1532 if (bank & 0x7fff8080)
1533 {
1534 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
1535 bank &= 0xff7f;
1536 }
1537 if (program > 127)
1538 {
1539 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
1540 program &= 0x7f;
1541 }
1542
1543 /* save the program number */
1544 *pLocale = (bank << 8) | program;
1545 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001546}
1547
1548/*----------------------------------------------------------------------------
1549 * Parse_lrgn ()
1550 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001551 * Purpose:
1552 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001553 *
1554 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001555 *
1556 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001557 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001558 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001559 *
1560 *----------------------------------------------------------------------------
1561*/
1562static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions)
1563{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001564 EAS_RESULT result;
1565 EAS_U32 temp;
1566 EAS_I32 chunkPos;
1567 EAS_I32 endChunk;
1568 EAS_U16 regionCount;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001569
Dave Sparks56c99cd2009-08-24 17:35:45 -07001570 /* seek to start of chunk */
1571 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1572 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001573
Dave Sparks56c99cd2009-08-24 17:35:45 -07001574 /* read to end of chunk */
1575 regionCount = 0;
1576 endChunk = pos + size;
1577 while (pos < endChunk)
1578 {
1579 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001580
Dave Sparks56c99cd2009-08-24 17:35:45 -07001581 /* get the next chunk type */
1582 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1583 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001584
Dave Sparks56c99cd2009-08-24 17:35:45 -07001585 if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
1586 {
1587 if (regionCount == numRegions)
1588 {
1589 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
1590 return EAS_SUCCESS;
1591 }
1592 if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
1593 return result;
1594 regionCount++;
1595 }
1596 }
1597
1598 /* set a flag in the last region */
1599 if ((pDLSData->pDLS != NULL) && (regionCount > 0))
1600 pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;
1601
1602 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001603}
1604
1605/*----------------------------------------------------------------------------
1606 * Parse_rgn ()
1607 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001608 * Purpose:
1609 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001610 *
1611 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001612 *
1613 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001614 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001615 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001616 *
1617 *----------------------------------------------------------------------------
1618*/
1619static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex)
1620{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001621 EAS_RESULT result;
1622 EAS_U32 temp;
1623 EAS_I32 chunkPos;
1624 EAS_I32 endChunk;
1625 EAS_I32 rgnhPos;
1626 EAS_I32 lartPos;
1627 EAS_I32 lartSize;
1628 EAS_I32 lar2Pos;
1629 EAS_I32 lar2Size;
1630 EAS_I32 wlnkPos;
1631 EAS_I32 wsmpPos;
1632 EAS_U32 waveIndex;
1633 S_DLS_ART_VALUES art;
1634 S_WSMP_DATA wsmp;
1635 S_WSMP_DATA *pWsmp;
1636 EAS_U16 regionIndex;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001637
Dave Sparks56c99cd2009-08-24 17:35:45 -07001638 /* seek to start of chunk */
1639 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1640 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001641
Dave Sparks56c99cd2009-08-24 17:35:45 -07001642 /* no chunks found yet */
1643 rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
1644 regionIndex = (EAS_U16) pDLSData->regionCount;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001645
Dave Sparks56c99cd2009-08-24 17:35:45 -07001646 /* read to end of chunk */
1647 endChunk = pos + size;
1648 while (pos < endChunk)
1649 {
1650 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001651
Dave Sparks56c99cd2009-08-24 17:35:45 -07001652 /* get the next chunk type */
1653 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1654 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001655
Dave Sparks56c99cd2009-08-24 17:35:45 -07001656 /* parse useful chunks */
1657 switch (temp)
1658 {
1659 case CHUNK_CDL:
1660 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
1661 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001662
Dave Sparks56c99cd2009-08-24 17:35:45 -07001663 /* if conditional chunk evaluates false, skip this list */
1664 if (!temp)
1665 return EAS_SUCCESS;
1666 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001667
Dave Sparks56c99cd2009-08-24 17:35:45 -07001668 case CHUNK_RGNH:
1669 rgnhPos = chunkPos + 8;
1670 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001671
Dave Sparks56c99cd2009-08-24 17:35:45 -07001672 case CHUNK_WLNK:
1673 wlnkPos = chunkPos + 8;
1674 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001675
Dave Sparks56c99cd2009-08-24 17:35:45 -07001676 case CHUNK_WSMP:
1677 wsmpPos = chunkPos + 8;
1678 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001679
Dave Sparks56c99cd2009-08-24 17:35:45 -07001680 case CHUNK_LART:
1681 lartPos = chunkPos + 12;
1682 lartSize = size;
1683 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001684
Dave Sparks56c99cd2009-08-24 17:35:45 -07001685 case CHUNK_LAR2:
1686 lar2Pos = chunkPos + 12;
1687 lar2Size = size;
1688 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001689
Dave Sparks56c99cd2009-08-24 17:35:45 -07001690 default:
1691 break;
1692 }
1693 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001694
Dave Sparks56c99cd2009-08-24 17:35:45 -07001695 /* must have a rgnh chunk to be useful */
1696 if (!rgnhPos)
1697 {
1698 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
1699 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1700 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001701
Dave Sparks56c99cd2009-08-24 17:35:45 -07001702 /* must have a wlnk chunk to be useful */
1703 if (!wlnkPos)
1704 {
1705 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
1706 return EAS_ERROR_UNRECOGNIZED_FORMAT;
1707 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001708
Dave Sparks56c99cd2009-08-24 17:35:45 -07001709 /* parse wlnk chunk */
1710 if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
1711 return result;
Wei Jiac5bc74d2015-08-20 16:25:04 -07001712 if (waveIndex >= pDLSData->waveCount)
1713 {
1714 return EAS_FAILURE;
1715 }
Dave Sparks56c99cd2009-08-24 17:35:45 -07001716 pWsmp = &pDLSData->wsmpData[waveIndex];
The Android Open Source Project7df30102009-03-03 19:30:38 -08001717
Dave Sparks56c99cd2009-08-24 17:35:45 -07001718 /* if there is any articulation data, parse it */
1719 EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
1720 if (lartPos)
1721 {
1722 if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
1723 return result;
1724 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001725
Dave Sparks56c99cd2009-08-24 17:35:45 -07001726 if (lar2Pos)
1727 {
1728 if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
1729 return result;
1730 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001731
Dave Sparks56c99cd2009-08-24 17:35:45 -07001732 /* if second pass, process region header */
1733 if (pDLSData->pDLS)
1734 {
1735
1736 /* if local data was found convert it */
1737 if (art.values[PARAM_MODIFIED] == EAS_TRUE)
1738 {
1739 Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
1740 artIndex = (EAS_U16) pDLSData->artCount;
1741 }
1742
1743 /* parse region header */
1744 if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
1745 return result;
1746
1747 /* parse wsmp chunk, copying parameters from original first */
1748 if (wsmpPos)
1749 {
1750 EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
1751 if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
1752 return result;
1753
1754 pWsmp = &wsmp;
1755 }
1756
1757 Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
Wei Jia40fc62b2015-08-21 13:41:42 -07001758
1759 /* ensure loopStart and loopEnd fall in the range */
1760 if (pWsmp->loopLength != 0)
1761 {
1762 EAS_U32 sampleLen = pDLSData->pDLS->pDLSSampleLen[waveIndex];
1763 if (sampleLen < sizeof(EAS_SAMPLE)
1764 || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE))
1765 {
1766 return EAS_FAILURE;
1767 }
1768 }
Dave Sparks56c99cd2009-08-24 17:35:45 -07001769 }
1770
1771 /* if local articulation, bump count */
1772 if (art.values[PARAM_MODIFIED])
1773 pDLSData->artCount++;
1774
1775 /* increment region count */
1776 pDLSData->regionCount++;
1777 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001778}
1779
1780/*----------------------------------------------------------------------------
1781 * Parse_rgnh ()
1782 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001783 * Purpose:
1784 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001785 *
1786 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001787 *
1788 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001789 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001790 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001791 *
1792 *----------------------------------------------------------------------------
1793*/
1794static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn)
1795{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001796 EAS_RESULT result;
1797 EAS_U16 lowKey;
1798 EAS_U16 highKey;
1799 EAS_U16 lowVel;
1800 EAS_U16 highVel;
1801 EAS_U16 optionFlags;
1802 EAS_U16 keyGroup;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001803
Dave Sparks56c99cd2009-08-24 17:35:45 -07001804 /* seek to start of chunk */
1805 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1806 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001807
Dave Sparks56c99cd2009-08-24 17:35:45 -07001808 /* get the key range */
1809 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
1810 return result;
1811 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
1812 return result;
1813
1814 /* check the range */
1815 if (lowKey > 127)
1816 {
1817 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
1818 lowKey = 127;
1819 }
1820 if (highKey > 127)
1821 {
1822 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
1823 highKey = 127;
1824 }
1825
1826 /* get the velocity range */
1827 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
1828 return result;
1829 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
1830 return result;
1831
1832 /* check the range */
1833 if (lowVel > 127)
1834 {
1835 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
1836 lowVel = 127;
1837 }
1838 if (highVel > 127)
1839 {
1840 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
1841 highVel = 127;
1842 }
1843
1844 /* get the option flags */
1845 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
1846 return result;
1847
1848 /* get the key group */
1849 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
1850 return result;
1851
1852 /* save the key range and key group */
1853 pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
1854 pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;
1855
1856 /*lint -e{734} keyGroup will always be from 0-15 */
1857 pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
1858 pRgn->velLow = (EAS_U8) lowVel;
1859 pRgn->velHigh = (EAS_U8) highVel;
1860 if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
1861 pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;
1862
1863 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001864}
1865
1866/*----------------------------------------------------------------------------
1867 * Parse_lart ()
1868 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001869 * Purpose:
1870 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001871 *
1872 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001873 *
1874 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001875 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001876 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001877 *
1878 *----------------------------------------------------------------------------
1879*/
1880static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt)
1881{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001882 EAS_RESULT result;
1883 EAS_U32 temp;
1884 EAS_I32 endChunk;
1885 EAS_I32 chunkPos;
1886 EAS_I32 art1Pos;
1887 EAS_I32 art2Pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001888
Dave Sparks56c99cd2009-08-24 17:35:45 -07001889 /* seek to start of chunk */
1890 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1891 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001892
Dave Sparks56c99cd2009-08-24 17:35:45 -07001893 /* no articulation chunks yet */
1894 art1Pos = art2Pos = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001895
Dave Sparks56c99cd2009-08-24 17:35:45 -07001896 /* read to end of chunk */
1897 endChunk = pos + size;
1898 while (pos < endChunk)
1899 {
1900 chunkPos = pos;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001901
Dave Sparks56c99cd2009-08-24 17:35:45 -07001902 /* get the next chunk type */
1903 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1904 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001905
Dave Sparks56c99cd2009-08-24 17:35:45 -07001906 /* parse useful chunks */
1907 switch (temp)
1908 {
1909 case CHUNK_CDL:
1910 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
1911 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001912
Dave Sparks56c99cd2009-08-24 17:35:45 -07001913 /* if conditional chunk evaluates false, skip this list */
1914 if (!temp)
1915 return EAS_SUCCESS;
1916 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001917
Dave Sparks56c99cd2009-08-24 17:35:45 -07001918 case CHUNK_ART1:
1919 art1Pos = chunkPos + 8;
1920 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001921
Dave Sparks56c99cd2009-08-24 17:35:45 -07001922 case CHUNK_ART2:
1923 art2Pos = chunkPos + 8;
1924 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001925
Dave Sparks56c99cd2009-08-24 17:35:45 -07001926 default:
1927 break;
1928
1929 }
1930 }
1931
1932 if (art1Pos)
1933 {
1934 if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
1935 return result;
1936 }
1937
1938 if (art2Pos)
1939 {
1940 if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
1941 return result;
1942 }
1943
1944 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001945}
1946
1947/*----------------------------------------------------------------------------
1948 * Parse_art()
1949 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001950 * Purpose:
1951 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001952 *
1953 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001954 *
1955 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001956 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001957 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001958 *
1959 *----------------------------------------------------------------------------
1960*/
1961static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt)
1962{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001963 EAS_RESULT result;
1964 EAS_U32 structSize;
1965 EAS_U32 numConnections;
1966 EAS_U16 source;
1967 EAS_U16 control;
1968 EAS_U16 destination;
1969 EAS_U16 transform;
1970 EAS_I32 scale;
1971 EAS_INT i;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001972
Dave Sparks56c99cd2009-08-24 17:35:45 -07001973 /* seek to start of data */
1974 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1975 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001976
Dave Sparks56c99cd2009-08-24 17:35:45 -07001977 /* get the structure size */
1978 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
1979 return result;
1980 pos += (EAS_I32) structSize;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001981
Dave Sparks56c99cd2009-08-24 17:35:45 -07001982 /* get the number of connections */
1983 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
1984 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001985
Dave Sparks56c99cd2009-08-24 17:35:45 -07001986 /* skip to start of connections */
1987 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1988 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001989
Dave Sparks56c99cd2009-08-24 17:35:45 -07001990 while (numConnections--)
1991 {
The Android Open Source Project7df30102009-03-03 19:30:38 -08001992
Dave Sparks56c99cd2009-08-24 17:35:45 -07001993 /* read the connection data */
1994 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
1995 return result;
1996 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
1997 return result;
1998 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
1999 return result;
2000 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
2001 return result;
2002 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
2003 return result;
2004
2005 /* look up the connection */
2006 for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
2007 {
2008 if ((connTable[i].source == source) &&
2009 (connTable[i].destination == destination) &&
2010 (connTable[i].control == control))
2011 {
2012 /*lint -e{704} use shift for performance */
2013 pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
2014 pArt->values[PARAM_MODIFIED] = EAS_TRUE;
2015 break;
2016 }
2017 }
2018 if (i == PARAM_TABLE_SIZE)
2019 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
2020 }
2021
2022 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002023}
2024
2025/*----------------------------------------------------------------------------
2026 * Parse_wlnk ()
2027 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002028 * Purpose:
2029 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002030 *
2031 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002032 *
2033 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002034 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002035 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002036 *
2037 *----------------------------------------------------------------------------
2038*/
2039static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex)
2040{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002041 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002042
Dave Sparks56c99cd2009-08-24 17:35:45 -07002043 /* we only care about the the index */
2044 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
2045 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002046
Dave Sparks56c99cd2009-08-24 17:35:45 -07002047 /* read the index */
2048 return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002049}
2050
2051/*----------------------------------------------------------------------------
2052 * PopcdlStack ()
2053 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002054 * Purpose:
2055 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002056 *
2057 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002058 *
2059 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002060 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002061 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002062 *
2063 *----------------------------------------------------------------------------
2064*/
2065static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue)
2066{
2067
Dave Sparks56c99cd2009-08-24 17:35:45 -07002068 /* stack underflow, cdl block has an errorr */
2069 if (*pStackPtr < 0)
2070 return EAS_ERROR_FILE_FORMAT;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002071
Dave Sparks56c99cd2009-08-24 17:35:45 -07002072 /* pop the value off the stack */
2073 *pValue = pStack[*pStackPtr];
2074 *pStackPtr = *pStackPtr - 1;
2075 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002076}
2077
2078/*----------------------------------------------------------------------------
2079 * PushcdlStack ()
2080 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002081 * Purpose:
2082 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002083 *
2084 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002085 *
2086 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002087 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002088 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002089 *
2090 *----------------------------------------------------------------------------
2091*/
2092static EAS_RESULT PushcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 value)
2093{
2094
Dave Sparks56c99cd2009-08-24 17:35:45 -07002095 /* stack overflow, return an error */
Wei Jiab01aa7d2017-02-07 10:35:31 -08002096 if (*pStackPtr >= (CDL_STACK_SIZE - 1)) {
2097 ALOGE("b/34031018, stackPtr(%d)", *pStackPtr);
2098 android_errorWriteLog(0x534e4554, "34031018");
Dave Sparks56c99cd2009-08-24 17:35:45 -07002099 return EAS_ERROR_FILE_FORMAT;
Wei Jiab01aa7d2017-02-07 10:35:31 -08002100 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002101
Dave Sparks56c99cd2009-08-24 17:35:45 -07002102 /* push the value onto the stack */
2103 *pStackPtr = *pStackPtr + 1;
2104 pStack[*pStackPtr] = value;
2105 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002106}
2107
2108/*----------------------------------------------------------------------------
2109 * QueryGUID ()
2110 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002111 * Purpose:
2112 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002113 *
2114 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002115 *
2116 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002117 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002118 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002119 *
2120 *----------------------------------------------------------------------------
2121*/
2122static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue)
2123{
2124
Dave Sparks56c99cd2009-08-24 17:35:45 -07002125 /* assume false */
2126 *pValue = 0;
2127 if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
2128 {
2129 *pValue = 0xffffffff;
2130 return EAS_TRUE;
2131 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002132
Dave Sparks56c99cd2009-08-24 17:35:45 -07002133 if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
2134 return EAS_TRUE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002135
Dave Sparks56c99cd2009-08-24 17:35:45 -07002136 if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
2137 return EAS_TRUE;
2138
2139 if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
2140 {
2141 *pValue = 0xffffffff;
2142 return EAS_TRUE;
2143 }
2144
2145 if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
2146 return EAS_TRUE;
2147
2148 if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
2149 {
2150 *pValue = MAX_DLS_MEMORY;
2151 return EAS_TRUE;
2152 }
2153
2154 if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
2155 {
2156 *pValue = 0x0000013A;
2157 return EAS_TRUE;
2158 }
2159
2160 if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
2161 {
2162 *pValue = LIB_VERSION;
2163 return EAS_TRUE;
2164 }
2165
2166 if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
2167 {
2168 *pValue = (EAS_U32) outputSampleRate;
2169 return EAS_TRUE;
2170 }
2171
2172 /* unrecognized DLSID */
2173 return EAS_FALSE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002174}
2175
2176/*----------------------------------------------------------------------------
2177 * ReadDLSID ()
2178 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002179 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002180 * Reads a DLSID in a manner that is not sensitive to processor endian-ness
2181 *
2182 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002183 *
2184 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002185 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002186 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002187 *
2188 *----------------------------------------------------------------------------
2189*/
2190static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID)
2191{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002192 EAS_RESULT result;
2193 EAS_I32 n;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002194
Dave Sparks56c99cd2009-08-24 17:35:45 -07002195 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
2196 return result;
2197 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
2198 return result;
2199 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
2200 return result;
2201 return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002202}
2203
2204/*----------------------------------------------------------------------------
2205 * Parse_cdl ()
2206 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002207 * Purpose:
2208 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002209 *
2210 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002211 *
2212 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002213 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002214 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002215 *
2216 *----------------------------------------------------------------------------
2217*/
2218static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue)
2219{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002220 EAS_RESULT result;
2221 EAS_U32 stack[CDL_STACK_SIZE];
2222 EAS_U16 opcode;
2223 EAS_INT stackPtr;
2224 EAS_U32 x, y;
2225 DLSID dlsid;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002226
Dave Sparks56c99cd2009-08-24 17:35:45 -07002227 stackPtr = -1;
2228 *pValue = 0;
2229 x = 0;
2230 while (size)
2231 {
2232 /* read the opcode */
2233 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
2234 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002235
Dave Sparks56c99cd2009-08-24 17:35:45 -07002236 /* handle binary opcodes */
2237 if (opcode <= DLS_CDL_EQ)
2238 {
2239 /* pop X and Y */
2240 if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
2241 return result;
2242 if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
2243 return result;
2244 switch (opcode)
2245 {
2246 case DLS_CDL_AND:
2247 x = x & y;
2248 break;
2249 case DLS_CDL_OR:
2250 x = x | y;
2251 break;
2252 case DLS_CDL_XOR:
2253 x = x ^ y;
2254 break;
2255 case DLS_CDL_ADD:
2256 x = x + y;
2257 break;
2258 case DLS_CDL_SUBTRACT:
2259 x = x - y;
2260 break;
2261 case DLS_CDL_MULTIPLY:
2262 x = x * y;
2263 break;
2264 case DLS_CDL_DIVIDE:
2265 if (!y)
2266 return EAS_ERROR_FILE_FORMAT;
2267 x = x / y;
2268 break;
2269 case DLS_CDL_LOGICAL_AND:
2270 x = (x && y);
2271 break;
2272 case DLS_CDL_LOGICAL_OR:
2273 x = (x || y);
2274 break;
2275 case DLS_CDL_LT:
2276 x = (x < y);
2277 break;
2278 case DLS_CDL_LE:
2279 x = (x <= y);
2280 break;
2281 case DLS_CDL_GT:
2282 x = (x > y);
2283 break;
2284 case DLS_CDL_GE:
2285 x = (x >= y);
2286 break;
2287 case DLS_CDL_EQ:
2288 x = (x == y);
2289 break;
2290 default:
2291 break;
2292 }
2293 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002294
Dave Sparks56c99cd2009-08-24 17:35:45 -07002295 else if (opcode == DLS_CDL_NOT)
2296 {
2297 if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
2298 return result;
2299 x = !x;
2300 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002301
Dave Sparks56c99cd2009-08-24 17:35:45 -07002302 else if (opcode == DLS_CDL_CONST)
2303 {
2304 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
2305 return result;
2306 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002307
Dave Sparks56c99cd2009-08-24 17:35:45 -07002308 else if (opcode == DLS_CDL_QUERY)
2309 {
2310 if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
2311 return result;
2312 QueryGUID(&dlsid, &x);
2313 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002314
Dave Sparks56c99cd2009-08-24 17:35:45 -07002315 else if (opcode == DLS_CDL_QUERYSUPPORTED)
2316 {
2317 if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
2318 return result;
2319 x = QueryGUID(&dlsid, &y);
2320 }
2321 else
2322 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }
2323
2324 /* push the result on the stack */
2325 if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
2326 return result;
2327 }
2328
2329 /* pop the last result off the stack */
2330 return PopcdlStack(stack, &stackPtr, pValue);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002331}
2332
2333/*----------------------------------------------------------------------------
2334 * Convert_rgn()
2335 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002336 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002337 * Convert region data from DLS to EAS
2338 *
2339 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002340 *
2341 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002342 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002343 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002344 *
2345 *----------------------------------------------------------------------------
2346*/
2347static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp)
2348{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002349 S_DLS_REGION *pRgn;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002350
Dave Sparks56c99cd2009-08-24 17:35:45 -07002351 /* setup pointers to data structures */
2352 pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002353
Dave Sparks56c99cd2009-08-24 17:35:45 -07002354 /* intiailize indices */
2355 pRgn->wtRegion.artIndex = artIndex;
2356 pRgn->wtRegion.waveIndex = waveIndex;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002357
Dave Sparks56c99cd2009-08-24 17:35:45 -07002358 /* convert region data */
2359 /*lint -e{704} use shift for performance */
2360 pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
2361 pRgn->wtRegion.loopStart = pWsmp->loopStart;
2362 pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
2363 pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
2364 if (pWsmp->loopLength != 0)
2365 pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002366}
2367
2368/*----------------------------------------------------------------------------
2369 * Convert_art()
2370 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002371 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002372 * Convert articulation data from DLS to EAS
2373 *
2374 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002375 *
2376 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002377 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07002378 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08002379 *
2380 *----------------------------------------------------------------------------
2381*/
2382static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex)
2383{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002384 S_DLS_ARTICULATION *pArt;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002385
Dave Sparks56c99cd2009-08-24 17:35:45 -07002386 /* setup pointers to data structures */
2387 pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002388
Dave Sparks56c99cd2009-08-24 17:35:45 -07002389 /* LFO parameters */
2390 pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
2391 pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
2392 pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
2393 pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002394
Dave Sparks56c99cd2009-08-24 17:35:45 -07002395 /* EG1 parameters */
2396 pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
2397 pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
2398 pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
2399 pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
2400 pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
2401 pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
2402 pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
2403 pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
2404 pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
2405 pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002406
Dave Sparks56c99cd2009-08-24 17:35:45 -07002407 /* EG2 parameters */
2408 pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
2409 pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
2410 pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
2411 pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
2412 pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
2413 pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
2414 pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
2415 pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
2416 pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002417
Dave Sparks56c99cd2009-08-24 17:35:45 -07002418 /* filter parameters */
2419 pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
2420 pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
2421 pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
2422 pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
2423 pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
2424 pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
2425 pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
2426 pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002427
Dave Sparks56c99cd2009-08-24 17:35:45 -07002428 /* gain parameters */
2429 pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
2430 pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
2431 pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002432
Dave Sparks56c99cd2009-08-24 17:35:45 -07002433 /* pitch parameters */
2434 pArt->tuning = pDLSArt->values[PARAM_TUNING];
2435 pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
2436 pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
2437 pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
2438 pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
2439 pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
2440 pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
2441 pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
2442 pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002443
Dave Sparks56c99cd2009-08-24 17:35:45 -07002444 /* output parameters */
2445 pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002446
Dave Sparks56c99cd2009-08-24 17:35:45 -07002447 if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
2448 pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002449
Dave Sparks56c99cd2009-08-24 17:35:45 -07002450#ifdef _REVERB
2451 pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
2452 pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
The Android Open Source Project7df30102009-03-03 19:30:38 -08002453#endif
2454
2455#ifdef _CHORUS
Dave Sparks56c99cd2009-08-24 17:35:45 -07002456 pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
2457 pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
2458#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -08002459}
2460
2461/*----------------------------------------------------------------------------
2462 * ConvertSampleRate()
2463 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002464 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002465 *
Dave Sparks56c99cd2009-08-24 17:35:45 -07002466 * Inputs:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002467 *
2468 * Outputs:
2469 *
2470 * Side Effects:
2471 *----------------------------------------------------------------------------
2472*/
2473static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
2474{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002475 return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
The Android Open Source Project7df30102009-03-03 19:30:38 -08002476}
2477
2478/*----------------------------------------------------------------------------
2479 * ConvertSustainEG2()
2480 *----------------------------------------------------------------------------
2481 * Convert sustain level to pitch/Fc multipler for EG2
2482 *----------------------------------------------------------------------------
2483*/
2484static EAS_I16 ConvertSustain (EAS_I32 sustain)
2485{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002486 /* check for sustain level of zero */
2487 if (sustain == 0)
2488 return 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002489
Dave Sparks56c99cd2009-08-24 17:35:45 -07002490 /* convert to log2 factor */
2491 /*lint -e{704} use shift for performance */
2492 sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002493
Dave Sparks56c99cd2009-08-24 17:35:45 -07002494 if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
2495 return SYNTH_FULL_SCALE_EG1_GAIN;
2496 return (EAS_I16) sustain;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002497}
2498
2499/*----------------------------------------------------------------------------
2500 * ConvertDelay ()
2501 *----------------------------------------------------------------------------
2502 * Converts timecents to frame count. Used for LFO and envelope
2503 * delay times.
2504 *----------------------------------------------------------------------------
2505*/
2506EAS_I16 ConvertDelay (EAS_I32 timeCents)
2507{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002508 EAS_I32 temp;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002509
Dave Sparks56c99cd2009-08-24 17:35:45 -07002510 if (timeCents == ZERO_TIME_IN_CENTS)
2511 return 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002512
Dave Sparks56c99cd2009-08-24 17:35:45 -07002513 /* divide time by secs per frame to get number of frames */
2514 temp = timeCents - dlsRateConvert;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002515
Dave Sparks56c99cd2009-08-24 17:35:45 -07002516 /* convert from time cents to 10-bit fraction */
2517 temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002518
Dave Sparks56c99cd2009-08-24 17:35:45 -07002519 /* convert to frame count */
2520 temp = EAS_LogToLinear16(temp - (15 << 10));
2521
2522 if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
2523 return (EAS_I16) temp;
2524 return SYNTH_FULL_SCALE_EG1_GAIN;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002525}
2526
2527/*----------------------------------------------------------------------------
2528 * ConvertRate ()
2529 *----------------------------------------------------------------------------
2530 * Convert timecents to rate
2531 *----------------------------------------------------------------------------
2532*/
2533EAS_I16 ConvertRate (EAS_I32 timeCents)
2534{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002535 EAS_I32 temp;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002536
Dave Sparks56c99cd2009-08-24 17:35:45 -07002537 if (timeCents == ZERO_TIME_IN_CENTS)
2538 return SYNTH_FULL_SCALE_EG1_GAIN;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002539
Dave Sparks56c99cd2009-08-24 17:35:45 -07002540 /* divide frame rate by time in log domain to get rate */
2541 temp = dlsRateConvert - timeCents;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002542
2543#if 1
Dave Sparks56c99cd2009-08-24 17:35:45 -07002544 temp = EAS_Calculate2toX(temp);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002545#else
Dave Sparks56c99cd2009-08-24 17:35:45 -07002546 /* convert from time cents to 10-bit fraction */
2547 temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
2548
2549 /* convert to rate */
2550 temp = EAS_LogToLinear16(temp);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002551#endif
2552
Dave Sparks56c99cd2009-08-24 17:35:45 -07002553 if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
2554 return (EAS_I16) temp;
2555 return SYNTH_FULL_SCALE_EG1_GAIN;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002556}
2557
2558
2559/*----------------------------------------------------------------------------
2560 * ConvertLFOPhaseIncrement()
2561 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002562 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002563 *
Dave Sparks56c99cd2009-08-24 17:35:45 -07002564 * Inputs:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002565 *
2566 * Outputs:
2567 *
2568 * Side Effects:
2569 *----------------------------------------------------------------------------
2570*/
2571static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
2572{
The Android Open Source Project7df30102009-03-03 19:30:38 -08002573
Dave Sparks56c99cd2009-08-24 17:35:45 -07002574 /* check range */
2575 if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
2576 pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
2577 if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
2578 pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002579
Dave Sparks56c99cd2009-08-24 17:35:45 -07002580 /* double the rate and divide by frame rate by subtracting in log domain */
2581 pitchCents = pitchCents - dlsLFOFrequencyConvert;
2582
2583 /* convert to phase increment */
2584 return (EAS_I16) EAS_Calculate2toX(pitchCents);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002585}
2586
2587/*----------------------------------------------------------------------------
2588 * ConvertPan()
2589 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07002590 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002591 *
Dave Sparks56c99cd2009-08-24 17:35:45 -07002592 * Inputs:
The Android Open Source Project7df30102009-03-03 19:30:38 -08002593 *
2594 * Outputs:
2595 *
2596 * Side Effects:
2597 *----------------------------------------------------------------------------
2598*/
2599static EAS_I8 ConvertPan (EAS_I32 pan)
2600{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002601
2602 /* multiply by conversion factor */
2603 pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
2604 if (pan < MIN_PAN_VALUE)
2605 return MIN_PAN_VALUE;
2606 if (pan > MAX_PAN_VALUE)
2607 return MAX_PAN_VALUE;
2608 return (EAS_I8) pan;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002609}
2610
2611/*----------------------------------------------------------------------------
2612 * ConvertQ()
2613 *----------------------------------------------------------------------------
2614 * Convert the DLS filter resonance to an index value used by the synth
2615 * that accesses tables of coefficients based on the Q.
2616 *----------------------------------------------------------------------------
2617*/
2618static EAS_U8 ConvertQ (EAS_I32 q)
2619{
2620
Dave Sparks56c99cd2009-08-24 17:35:45 -07002621 /* apply limits */
2622 if (q <= 0)
2623 return 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002624
Dave Sparks56c99cd2009-08-24 17:35:45 -07002625 /* convert to table index */
2626 /*lint -e{704} use shift for performance */
2627 q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002628
Dave Sparks56c99cd2009-08-24 17:35:45 -07002629 /* apply upper limit */
2630 if (q >= FILTER_RESONANCE_NUM_ENTRIES)
2631 q = FILTER_RESONANCE_NUM_ENTRIES - 1;
2632 return (EAS_U8) q;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002633}
2634
2635#ifdef _DEBUG_DLS
2636/*----------------------------------------------------------------------------
2637 * DumpDLS()
2638 *----------------------------------------------------------------------------
2639*/
2640static void DumpDLS (S_EAS *pEAS)
2641{
Dave Sparks56c99cd2009-08-24 17:35:45 -07002642 S_DLS_ARTICULATION *pArt;
2643 S_DLS_REGION *pRegion;
2644 EAS_INT i;
2645 EAS_INT j;
The Android Open Source Project7df30102009-03-03 19:30:38 -08002646
Dave Sparks56c99cd2009-08-24 17:35:45 -07002647 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
2648 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
2649 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
2650 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002651
Dave Sparks56c99cd2009-08-24 17:35:45 -07002652 /* dump the instruments */
2653 for (i = 0; i < pEAS->numPrograms; i++)
2654 {
2655 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
2656 pEAS->pPrograms[i].locale >> 16,
2657 (pEAS->pPrograms[i].locale >> 8) & 0x7f,
2658 pEAS->pPrograms[i].locale & 0x7f);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002659
Dave Sparks56c99cd2009-08-24 17:35:45 -07002660 for (j = pEAS->pPrograms[i].regionIndex; ; j++)
2661 {
2662 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
2663 pRegion = &pEAS->pWTRegions[j];
2664 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
2665 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
2666 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
2667 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
2668 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
2669 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
2670 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
2671 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002672
Dave Sparks56c99cd2009-08-24 17:35:45 -07002673 if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
2674 break;
2675 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002676
Dave Sparks56c99cd2009-08-24 17:35:45 -07002677 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002678
Dave Sparks56c99cd2009-08-24 17:35:45 -07002679 /* dump the articulation data */
2680 for (i = 0; i < pEAS->numDLSArticulations; i++)
2681 {
2682 /* articulation data */
2683 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
2684 pArt = &pEAS->pDLSArticulations[i];
2685 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
2686 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
2687 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
2688 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
2689 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
2690 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
2691 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
2692 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
2693 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002694
Dave Sparks56c99cd2009-08-24 17:35:45 -07002695 /* EG1 data */
2696 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
2697 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
2698 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
2699 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);
The Android Open Source Project7df30102009-03-03 19:30:38 -08002700
Dave Sparks56c99cd2009-08-24 17:35:45 -07002701 /* EG2 data */
2702 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
2703 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
2704 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
2705 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);
2706
2707 }
2708
2709 /* dump the waves */
2710 for (i = 0; i < pEAS->numSamples; i++)
2711 {
2712 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
2713 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
2714 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
2715 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08002716
2717}
2718#endif
2719