blob: b3161f0720fc012ca7696aa7c04d5d997be4de8d [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_public.c
5 *
6 * Contents and purpose:
7 * Contains EAS library public interface
Dave Sparks56c99cd2009-08-24 17:35:45 -07008 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08009 * Copyright Sonic Network Inc. 2004
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: 842 $
26 * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
27 *----------------------------------------------------------------------------
28*/
29
Phil Burkc71f73a2018-06-19 08:19:05 -070030#define LOG_TAG "Sonivox"
31#include "log/log.h"
32
The Android Open Source Project7df30102009-03-03 19:30:38 -080033#include "eas_synthcfg.h"
34#include "eas.h"
35#include "eas_config.h"
36#include "eas_host.h"
37#include "eas_report.h"
38#include "eas_data.h"
39#include "eas_parser.h"
40#include "eas_pcm.h"
41#include "eas_midi.h"
42#include "eas_mixer.h"
43#include "eas_build.h"
44#include "eas_vm_protos.h"
45#include "eas_math.h"
46
47#ifdef JET_INTERFACE
48#include "jet_data.h"
49#endif
50
51#ifdef DLS_SYNTHESIZER
52#include "eas_mdls.h"
53#endif
54
55/* number of events to parse before calling EAS_HWYield function */
Dave Sparks56c99cd2009-08-24 17:35:45 -070056#define YIELD_EVENT_COUNT 10
The Android Open Source Project7df30102009-03-03 19:30:38 -080057
58/*----------------------------------------------------------------------------
59 * easLibConfig
60 *
61 * This structure is available through the EAS public interface to allow
62 * the user to check the configuration of the library.
63 *----------------------------------------------------------------------------
64*/
65static const S_EAS_LIB_CONFIG easLibConfig =
66{
Dave Sparks56c99cd2009-08-24 17:35:45 -070067 LIB_VERSION,
The Android Open Source Project7df30102009-03-03 19:30:38 -080068#ifdef _CHECKED_BUILD
Dave Sparks56c99cd2009-08-24 17:35:45 -070069 EAS_TRUE,
The Android Open Source Project7df30102009-03-03 19:30:38 -080070#else
Dave Sparks56c99cd2009-08-24 17:35:45 -070071 EAS_FALSE,
The Android Open Source Project7df30102009-03-03 19:30:38 -080072#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -070073 MAX_SYNTH_VOICES,
74 NUM_OUTPUT_CHANNELS,
75 _OUTPUT_SAMPLE_RATE,
76 BUFFER_SIZE_IN_MONO_SAMPLES,
The Android Open Source Project7df30102009-03-03 19:30:38 -080077#ifdef _FILTER_ENABLED
Dave Sparks56c99cd2009-08-24 17:35:45 -070078 EAS_TRUE,
The Android Open Source Project7df30102009-03-03 19:30:38 -080079#else
Dave Sparks56c99cd2009-08-24 17:35:45 -070080 EAS_FALSE,
The Android Open Source Project7df30102009-03-03 19:30:38 -080081#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -070082 _BUILD_TIME_,
83 _BUILD_VERSION_
The Android Open Source Project7df30102009-03-03 19:30:38 -080084};
85
86/* local prototypes */
87static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
88
89/*----------------------------------------------------------------------------
90 * EAS_SetStreamParameter
91 *----------------------------------------------------------------------------
92 * Sets the specified parameter in the stream. Allows access to
93 * customizable settings within the individual file parsers.
94 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -070095 * pEASData - pointer to EAS persistent data object
96 * pStream - stream handle
97 * param - enumerated parameter (see eas_parser.h)
98 * value - new value
The Android Open Source Project7df30102009-03-03 19:30:38 -080099 *----------------------------------------------------------------------------
100*/
101EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
102{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700103 S_FILE_PARSER_INTERFACE *pParserModule;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800104
Dave Sparks56c99cd2009-08-24 17:35:45 -0700105 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
106 if (pParserModule->pfSetData)
107 return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
108 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800109}
110
111/*----------------------------------------------------------------------------
112 * EAS_GetStreamParameter
113 *----------------------------------------------------------------------------
114 * Sets the specified parameter in the stream. Allows access to
115 * customizable settings within the individual file parsers.
116 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700117 * pEASData - pointer to EAS persistent data object
118 * pStream - stream handle
119 * param - enumerated parameter (see eas_parser.h)
120 * pValue - pointer to variable to receive current setting
The Android Open Source Project7df30102009-03-03 19:30:38 -0800121 *----------------------------------------------------------------------------
122*/
123EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
124{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700125 S_FILE_PARSER_INTERFACE *pParserModule;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800126
Dave Sparks56c99cd2009-08-24 17:35:45 -0700127 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
128 if (pParserModule->pfGetData)
129 return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
130 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800131}
132
133/*----------------------------------------------------------------------------
134 * EAS_StreamReady()
135 *----------------------------------------------------------------------------
136 * This routine sets common parameters like transpose, volume, etc.
137 * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
138 * fails, it attempts to get the synth handle from the parser and
139 * set the parameter directly on the synth. This eliminates duplicate
140 * code in the parser.
141 *----------------------------------------------------------------------------
142*/
143EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
144{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700145 S_FILE_PARSER_INTERFACE *pParserModule;
146 EAS_STATE state;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800147
Dave Sparks56c99cd2009-08-24 17:35:45 -0700148 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
149 if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
150 return EAS_FALSE;
151 return (state < EAS_STATE_OPEN);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800152}
153
154/*----------------------------------------------------------------------------
155 * EAS_IntSetStrmParam()
156 *----------------------------------------------------------------------------
157 * This routine sets common parameters like transpose, volume, etc.
158 * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
159 * fails, it attempts to get the synth handle from the parser and
160 * set the parameter directly on the synth. This eliminates duplicate
161 * code in the parser.
162 *----------------------------------------------------------------------------
163*/
164EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
165{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700166 S_SYNTH *pSynth;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800167
Dave Sparks56c99cd2009-08-24 17:35:45 -0700168 /* try to set the parameter using stream interface */
169 if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
170 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800171
Dave Sparks56c99cd2009-08-24 17:35:45 -0700172 /* get a pointer to the synth object and set it directly */
173 /*lint -e{740} we are cheating by passing a pointer through this interface */
174 if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
175 return EAS_ERROR_INVALID_PARAMETER;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800176
Dave Sparks56c99cd2009-08-24 17:35:45 -0700177 if (pSynth == NULL)
178 return EAS_ERROR_INVALID_PARAMETER;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800179
Dave Sparks56c99cd2009-08-24 17:35:45 -0700180 switch (param)
181 {
182
183#ifdef DLS_SYNTHESIZER
184 case PARSER_DATA_DLS_COLLECTION:
185 {
186 EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
187 if (result == EAS_SUCCESS)
188 {
189 DLSAddRef((S_DLS*) value);
190 VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
191 }
192 return result;
193 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800194#endif
195
Dave Sparks56c99cd2009-08-24 17:35:45 -0700196 case PARSER_DATA_EAS_LIBRARY:
197 return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
198
199 case PARSER_DATA_POLYPHONY:
200 return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
201
202 case PARSER_DATA_PRIORITY:
203 return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
204
205 case PARSER_DATA_TRANSPOSITION:
206 VMSetTranposition(pSynth, value);
207 break;
208
209 case PARSER_DATA_VOLUME:
210 VMSetVolume(pSynth, (EAS_U16) value);
211 break;
212
213 default:
214 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
215 return EAS_ERROR_INVALID_PARAMETER;
216 }
217
218 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800219}
220
221/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -0800222 * EAS_AllocateStream()
223 *----------------------------------------------------------------------------
224 * Purpose:
225 * Allocates a stream handle
226 *
227 * Inputs:
228 *
229 * Outputs:
230 *
231 *----------------------------------------------------------------------------
232*/
233static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
234{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700235 EAS_INT streamNum;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800236
Dave Sparks56c99cd2009-08-24 17:35:45 -0700237 /* check for static allocation, only one stream allowed */
238 if (pEASData->staticMemoryModel)
239 {
240 if (pEASData->streams[0].handle != NULL)
241 {
242 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
243 return -1;
244 }
245 return 0;
246 }
247
248 /* dynamic model */
249 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
250 if (pEASData->streams[streamNum].handle == NULL)
251 break;
252 if (streamNum == MAX_NUMBER_STREAMS)
253 {
254 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
255 return -1;
256 }
257 return streamNum;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800258}
259
260/*----------------------------------------------------------------------------
261 * EAS_InitStream()
262 *----------------------------------------------------------------------------
263 * Purpose:
264 * Initialize a stream
265 *
266 * Inputs:
267 *
268 * Outputs:
269 *
270 *----------------------------------------------------------------------------
271*/
272static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
273{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700274 pStream->pParserModule = pParserModule;
275 pStream->handle = streamHandle;
276 pStream->time = 0;
277 pStream->frameLength = AUDIO_FRAME_LENGTH;
278 pStream->repeatCount = 0;
279 pStream->volume = DEFAULT_STREAM_VOLUME;
280 pStream->streamFlags = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800281}
282
283/*----------------------------------------------------------------------------
284 * EAS_Config()
285 *----------------------------------------------------------------------------
286 * Purpose:
287 * Returns a pointer to a structure containing the configuration options
288 * in this library build.
289 *
290 * Inputs:
291 *
292 * Outputs:
293 *
294 *----------------------------------------------------------------------------
295*/
296EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
297{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700298 return &easLibConfig;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800299}
300
301/*----------------------------------------------------------------------------
302 * EAS_Init()
303 *----------------------------------------------------------------------------
304 * Purpose:
305 * Initialize the synthesizer library
306 *
307 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700308 * ppEASData - pointer to data handle variable for this instance
The Android Open Source Project7df30102009-03-03 19:30:38 -0800309 *
310 * Outputs:
311 *
312 *----------------------------------------------------------------------------
313*/
314EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
315{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700316 EAS_HW_DATA_HANDLE pHWInstData;
317 EAS_RESULT result;
318 S_EAS_DATA *pEASData;
319 EAS_INT module;
320 EAS_BOOL staticMemoryModel;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800321
Dave Sparks56c99cd2009-08-24 17:35:45 -0700322 /* get the memory model */
323 staticMemoryModel = EAS_CMStaticMemoryModel();
The Android Open Source Project7df30102009-03-03 19:30:38 -0800324
Dave Sparks56c99cd2009-08-24 17:35:45 -0700325 /* initialize the host wrapper interface */
326 *ppEASData = NULL;
327 if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
328 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800329
Dave Sparks56c99cd2009-08-24 17:35:45 -0700330 /* check Configuration Module for S_EAS_DATA allocation */
331 if (staticMemoryModel)
332 pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
333 else
334 pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
335 if (!pEASData)
336 {
337 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
338 return EAS_ERROR_MALLOC_FAILED;
339 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800340
Dave Sparks56c99cd2009-08-24 17:35:45 -0700341 /* initialize some data */
342 EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
343 pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
344 pEASData->hwInstData = pHWInstData;
345 pEASData->renderTime = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800346
Dave Sparks56c99cd2009-08-24 17:35:45 -0700347 /* set header search flag */
348#ifdef FILE_HEADER_SEARCH
349 pEASData->searchHeaderFlag = EAS_TRUE;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800350#endif
351
Dave Sparks56c99cd2009-08-24 17:35:45 -0700352 /* initalize parameters */
353 EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800354
355#ifdef _METRICS_ENABLED
Dave Sparks56c99cd2009-08-24 17:35:45 -0700356 /* initalize the metrics module */
357 pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
358 if (pEASData->pMetricsModule != NULL)
359 {
360 if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
361 {
362 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
363 return result;
364 }
365 }
366#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -0800367
Dave Sparks56c99cd2009-08-24 17:35:45 -0700368 /* initailize the voice manager & synthesizer */
369 if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
370 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800371
Dave Sparks56c99cd2009-08-24 17:35:45 -0700372 /* initialize mix engine */
373 if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
374 {
375 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
376 return result;
377 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800378
Dave Sparks56c99cd2009-08-24 17:35:45 -0700379 /* initialize effects modules */
380 for (module = 0; module < NUM_EFFECTS_MODULES; module++)
381 {
382 pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
383 if (pEASData->effectsModules[module].effect != NULL)
384 {
385 if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
386 {
387 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
388 return result;
389 }
390 }
391 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800392
Dave Sparks56c99cd2009-08-24 17:35:45 -0700393 /* initialize PCM engine */
394 if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
395 {
396 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
397 return result;
398 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800399
Dave Sparks56c99cd2009-08-24 17:35:45 -0700400 /* return instance data pointer to host */
401 *ppEASData = pEASData;
402
403 return EAS_SUCCESS;
404}
The Android Open Source Project7df30102009-03-03 19:30:38 -0800405
406/*----------------------------------------------------------------------------
407 * EAS_Shutdown()
408 *----------------------------------------------------------------------------
409 * Purpose:
410 * Shuts down the library. Deallocates any memory associated with the
411 * synthesizer (dynamic memory model only)
412 *
413 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700414 * pEASData - handle to data for this instance
The Android Open Source Project7df30102009-03-03 19:30:38 -0800415 *
416 * Outputs:
417 *
418 *----------------------------------------------------------------------------
419*/
420EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
421{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700422 /* check for NULL handle */
423 if (!pEASData)
424 return EAS_ERROR_HANDLE_INTEGRITY;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800425
liuchao6040cfa2017-04-13 10:48:51 +0800426 /* establish pointers */
427 EAS_HW_DATA_HANDLE hwInstData = pEASData->hwInstData;
428
Dave Sparks56c99cd2009-08-24 17:35:45 -0700429 /* if there are streams open, close them */
liuchao6040cfa2017-04-13 10:48:51 +0800430 EAS_RESULT reportResult = EAS_SUCCESS;
431
432 EAS_RESULT result;
433 EAS_INT i;
Dave Sparks56c99cd2009-08-24 17:35:45 -0700434 for (i = 0; i < MAX_NUMBER_STREAMS; i++)
435 {
436 if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
437 {
438 if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
439 {
440 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
441 reportResult = result;
442 }
443 }
444 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800445
Dave Sparks56c99cd2009-08-24 17:35:45 -0700446 /* shutdown PCM engine */
447 if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
448 {
449 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
450 if (reportResult == EAS_SUCCESS)
451 reportResult = result;
452 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800453
Dave Sparks56c99cd2009-08-24 17:35:45 -0700454 /* shutdown mix engine */
455 if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
456 {
457 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
458 if (reportResult == EAS_SUCCESS)
459 reportResult = result;
460 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800461
Dave Sparks56c99cd2009-08-24 17:35:45 -0700462 /* shutdown effects modules */
463 for (i = 0; i < NUM_EFFECTS_MODULES; i++)
464 {
465 if (pEASData->effectsModules[i].effect)
466 {
467 if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
468 {
469 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
470 if (reportResult == EAS_SUCCESS)
471 reportResult = result;
472 }
473 }
474 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800475
Dave Sparks56c99cd2009-08-24 17:35:45 -0700476 /* shutdown the voice manager & synthesizer */
477 VMShutdown(pEASData);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800478
Dave Sparks56c99cd2009-08-24 17:35:45 -0700479#ifdef _METRICS_ENABLED
480 /* shutdown the metrics module */
481 if (pEASData->pMetricsModule != NULL)
482 {
483 if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
484 {
485 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
486 if (reportResult == EAS_SUCCESS)
487 reportResult = result;
488 }
489 }
490#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -0800491
Dave Sparks56c99cd2009-08-24 17:35:45 -0700492 /* release allocated memory */
493 if (!pEASData->staticMemoryModel)
494 EAS_HWFree(hwInstData, pEASData);
495
496 /* shutdown host wrappers */
497 if (hwInstData)
498 {
499 if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
500 {
501 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
502 if (reportResult == EAS_SUCCESS)
503 reportResult = result;
504 }
505 }
506
507 return reportResult;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800508}
509
510#ifdef JET_INTERFACE
511/*----------------------------------------------------------------------------
512 * EAS_OpenJETStream()
513 *----------------------------------------------------------------------------
514 * Private interface for JET to open an SMF stream with an offset
515 *----------------------------------------------------------------------------
516*/
517EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
518{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700519 EAS_RESULT result;
520 EAS_VOID_PTR streamHandle;
521 S_FILE_PARSER_INTERFACE *pParserModule;
522 EAS_INT streamNum;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800523
Dave Sparks56c99cd2009-08-24 17:35:45 -0700524 /* allocate a stream */
525 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
526 return EAS_ERROR_MAX_STREAMS_OPEN;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800527
Dave Sparks56c99cd2009-08-24 17:35:45 -0700528 /* check Configuration Module for SMF parser */
529 *ppStream = NULL;
530 streamHandle = NULL;
531 pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
532 if (pParserModule == NULL)
533 return EAS_ERROR_UNRECOGNIZED_FORMAT;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800534
Dave Sparks56c99cd2009-08-24 17:35:45 -0700535 /* see if SMF parser recognizes the file */
536 if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
537 {
538 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
539 return result;
540 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800541
Dave Sparks56c99cd2009-08-24 17:35:45 -0700542 /* parser recognized the file, return the handle */
543 if (streamHandle)
544 {
545 EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
546 *ppStream = &pEASData->streams[streamNum];
547 return EAS_SUCCESS;
548 }
549
550 return EAS_ERROR_UNRECOGNIZED_FORMAT;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800551}
552#endif
553
554/*----------------------------------------------------------------------------
555 * EAS_OpenFile()
556 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700557 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800558 * Opens a file for audio playback.
559 *
560 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700561 * pEASData - pointer to overall EAS data structure
562 * pHandle - pointer to file handle
563 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800564 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700565 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800566 *
567 * Side Effects:
568 *
569 *----------------------------------------------------------------------------
570*/
571EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
572{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700573 EAS_RESULT result;
574 EAS_FILE_HANDLE fileHandle;
575 EAS_VOID_PTR streamHandle;
576 S_FILE_PARSER_INTERFACE *pParserModule;
577 EAS_INT streamNum;
578 EAS_INT moduleNum;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800579
Dave Sparks56c99cd2009-08-24 17:35:45 -0700580 /* open the file */
581 if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
582 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800583
Dave Sparks56c99cd2009-08-24 17:35:45 -0700584 /* allocate a stream */
585 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
gbhakteXa965c0d2012-07-26 18:53:25 +0530586 {
587 /* Closing the opened file as stream allocation failed */
588 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
Dave Sparks56c99cd2009-08-24 17:35:45 -0700589 return EAS_ERROR_MAX_STREAMS_OPEN;
gbhakteXa965c0d2012-07-26 18:53:25 +0530590 }
Dave Sparks56c99cd2009-08-24 17:35:45 -0700591 /* check Configuration Module for file parsers */
592 pParserModule = NULL;
593 *ppStream = NULL;
594 streamHandle = NULL;
595 for (moduleNum = 0; ; moduleNum++)
596 {
597 pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
598 if (pParserModule == NULL)
599 break;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800600
Dave Sparks56c99cd2009-08-24 17:35:45 -0700601 /* see if this parser recognizes it */
602 if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
603 {
gbhakteXa965c0d2012-07-26 18:53:25 +0530604 /* Closing the opened file as file type check failed */
605 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
606
Dave Sparks56c99cd2009-08-24 17:35:45 -0700607 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
608 return result;
609 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800610
Dave Sparks56c99cd2009-08-24 17:35:45 -0700611 /* parser recognized the file, return the handle */
612 if (streamHandle)
613 {
The Android Open Source Project7df30102009-03-03 19:30:38 -0800614
Dave Sparks56c99cd2009-08-24 17:35:45 -0700615 /* save the parser pointer and file handle */
616 EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
617 *ppStream = &pEASData->streams[streamNum];
618 return EAS_SUCCESS;
619 }
620
621 /* rewind the file for the next parser */
622 if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
gbhakteXa965c0d2012-07-26 18:53:25 +0530623 {
624 /* Closing the opened file as file seek failed */
625 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
626
Dave Sparks56c99cd2009-08-24 17:35:45 -0700627 return result;
gbhakteXa965c0d2012-07-26 18:53:25 +0530628 }
Dave Sparks56c99cd2009-08-24 17:35:45 -0700629 }
630
631 /* no parser was able to recognize the file, close it and return an error */
632 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
633 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
634 return EAS_ERROR_UNRECOGNIZED_FORMAT;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800635}
636
The Android Open Source Project7df30102009-03-03 19:30:38 -0800637/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -0800638 * EAS_Prepare()
639 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700640 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800641 * Prepares the synthesizer to play the file or stream. Parses the first
642 * frame of data from the file and arms the synthesizer.
643 *
644 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700645 * pEASData - pointer to overall EAS data structure
646 * handle - file or stream handle
647 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800648 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700649 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800650 *
651 * Side Effects:
652 *
653 *----------------------------------------------------------------------------
654*/
655EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
656{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700657 S_FILE_PARSER_INTERFACE *pParserModule;
658 EAS_STATE state;
659 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800660
Dave Sparks56c99cd2009-08-24 17:35:45 -0700661 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
662 if (pParserModule == NULL)
663 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800664
Dave Sparks56c99cd2009-08-24 17:35:45 -0700665 /* check for valid state */
666 result = pParserModule->pfState(pEASData, pStream->handle, &state);
667 if (result == EAS_SUCCESS)
668 {
669 /* prepare the stream */
670 if (state == EAS_STATE_OPEN)
671 {
672 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
673 result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
674
675 /* set volume */
676 if (result == EAS_SUCCESS)
677 result = EAS_SetVolume(pEASData, pStream, pStream->volume);
678 }
679 else
680 result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
681
682 }
683
684 return result;
685}
The Android Open Source Project7df30102009-03-03 19:30:38 -0800686
687/*----------------------------------------------------------------------------
688 * EAS_Render()
689 *----------------------------------------------------------------------------
690 * Purpose:
691 * Parse the Midi data and render PCM audio data.
692 *
693 * Inputs:
694 * pEASData - buffer for internal EAS data
Dave Sparks56c99cd2009-08-24 17:35:45 -0700695 * pOut - output buffer pointer
696 * nNumRequested - requested num samples to generate
697 * pnNumGenerated - actual number of samples generated
The Android Open Source Project7df30102009-03-03 19:30:38 -0800698 *
699 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700700 * EAS_SUCCESS if PCM data was successfully rendered
The Android Open Source Project7df30102009-03-03 19:30:38 -0800701 *
702 *----------------------------------------------------------------------------
703*/
704EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
705{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700706 S_FILE_PARSER_INTERFACE *pParserModule;
707 EAS_RESULT result;
708 EAS_I32 voicesRendered;
709 EAS_STATE parserState;
710 EAS_INT streamNum;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800711
Dave Sparks56c99cd2009-08-24 17:35:45 -0700712 /* assume no samples generated and reset workload */
713 *pNumGenerated = 0;
714 VMInitWorkload(pEASData->pVoiceMgr);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800715
Dave Sparks56c99cd2009-08-24 17:35:45 -0700716 /* no support for other buffer sizes yet */
717 if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
718 {
719 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
720 (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
721 return EAS_BUFFER_SIZE_MISMATCH;
722 }
723
724#ifdef _METRICS_ENABLED
725 /* start performance counter */
726 if (pEASData->pMetricsData)
727 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800728#endif
729
Dave Sparks56c99cd2009-08-24 17:35:45 -0700730 /* prep the frame buffer, do mix engine prep only if TRUE */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800731#ifdef _SPLIT_ARCHITECTURE
Dave Sparks56c99cd2009-08-24 17:35:45 -0700732 if (VMStartFrame(pEASData))
733 EAS_MixEnginePrep(pEASData, numRequested);
734#else
735 /* prep the mix engine */
736 EAS_MixEnginePrep(pEASData, numRequested);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800737#endif
738
Dave Sparks56c99cd2009-08-24 17:35:45 -0700739 /* save the output buffer pointer */
740 pEASData->pOutputAudioBuffer = pOut;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800741
742
Dave Sparks56c99cd2009-08-24 17:35:45 -0700743#ifdef _METRICS_ENABLED
744 /* start performance counter */
745 if (pEASData->pMetricsData)
746 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800747#endif
748
Dave Sparks56c99cd2009-08-24 17:35:45 -0700749 /* if we haven't finished parsing from last time, do it now */
750 /* need to parse another frame of events before we render again */
751 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
752 {
753 /* clear the locate flag */
754 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800755
Dave Sparks56c99cd2009-08-24 17:35:45 -0700756 if (pEASData->streams[streamNum].pParserModule)
757 {
The Android Open Source Project7df30102009-03-03 19:30:38 -0800758
Dave Sparks56c99cd2009-08-24 17:35:45 -0700759 /* establish pointer to parser module */
760 pParserModule = pEASData->streams[streamNum].pParserModule;
761
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700762#ifdef JET_INTERFACE
Dave Sparks56c99cd2009-08-24 17:35:45 -0700763 /* handle pause */
764 if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
765 {
766 if (pParserModule->pfPause)
767 result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
768 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
769 }
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700770#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -0700771
772 /* get current state */
773 if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
774 return result;
775
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700776#ifdef JET_INTERFACE
Dave Sparks56c99cd2009-08-24 17:35:45 -0700777 /* handle resume */
778 if (parserState == EAS_STATE_PAUSED)
779 {
780 if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
781 {
782 if (pParserModule->pfResume)
783 result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
784 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
785 }
786 }
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700787#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -0700788
789 /* if necessary, parse stream */
790 if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
791 if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
792 return result;
793
794 /* check for an early abort */
795 if ((pEASData->streams[streamNum].streamFlags) == 0)
796 {
797
798#ifdef _METRICS_ENABLED
799 /* stop performance counter */
800 if (pEASData->pMetricsData)
801 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800802#endif
803
Dave Sparks56c99cd2009-08-24 17:35:45 -0700804 return EAS_SUCCESS;
805 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800806
Dave Sparks56c99cd2009-08-24 17:35:45 -0700807 /* check for repeat */
808 if (pEASData->streams[streamNum].repeatCount)
809 {
810
811 /* check for stopped state */
812 if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
813 return result;
814 if (parserState == EAS_STATE_STOPPED)
815 {
816
817 /* decrement repeat count, unless it is negative */
818 if (pEASData->streams[streamNum].repeatCount > 0)
819 pEASData->streams[streamNum].repeatCount--;
820
821 /* reset the parser */
822 if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
823 return result;
824 pEASData->streams[streamNum].time = 0;
825 }
826 }
827 }
828 }
829
830#ifdef _METRICS_ENABLED
831 /* stop performance counter */
832 if (pEASData->pMetricsData)
833 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800834#endif
835
Dave Sparks56c99cd2009-08-24 17:35:45 -0700836#ifdef _METRICS_ENABLED
837 /* start the render timer */
838 if (pEASData->pMetricsData)
839 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800840#endif
841
Dave Sparks56c99cd2009-08-24 17:35:45 -0700842 /* render audio */
843 if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
844 {
845 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
846 return result;
847 }
848
849#ifdef _METRICS_ENABLED
850 /* stop the render timer */
851 if (pEASData->pMetricsData) {
852 (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
853 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
854 (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
855 (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
856 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800857#endif
858
Dave Sparks56c99cd2009-08-24 17:35:45 -0700859 //2 Do we really need frameParsed?
860 /* need to parse another frame of events before we render again */
861 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
862 if (pEASData->streams[streamNum].pParserModule != NULL)
863 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
864
865#ifdef _METRICS_ENABLED
866 /* start performance counter */
867 if (pEASData->pMetricsData)
868 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800869#endif
870
Dave Sparks56c99cd2009-08-24 17:35:45 -0700871#ifdef _METRICS_ENABLED
872 /* stop the stream timer */
873 if (pEASData->pMetricsData)
874 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
875#endif
876
877#ifdef _METRICS_ENABLED
878 /* start the post timer */
879 if (pEASData->pMetricsData)
880 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
881#endif
882
883 /* for split architecture, send DSP vectors. Do post only if return is TRUE */
The Android Open Source Project7df30102009-03-03 19:30:38 -0800884#ifdef _SPLIT_ARCHITECTURE
Dave Sparks56c99cd2009-08-24 17:35:45 -0700885 if (VMEndFrame(pEASData))
886 {
887 /* now do post-processing */
888 EAS_MixEnginePost(pEASData, numRequested);
889 *pNumGenerated = numRequested;
890 }
891#else
892 /* now do post-processing */
893 EAS_MixEnginePost(pEASData, numRequested);
894 *pNumGenerated = numRequested;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800895#endif
896
Dave Sparks56c99cd2009-08-24 17:35:45 -0700897#ifdef _METRICS_ENABLED
898 /* stop the post timer */
899 if (pEASData->pMetricsData)
900 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800901#endif
902
Dave Sparks56c99cd2009-08-24 17:35:45 -0700903 /* advance render time */
904 pEASData->renderTime += AUDIO_FRAME_LENGTH;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800905
906#if 0
Dave Sparks56c99cd2009-08-24 17:35:45 -0700907 /* dump workload for debug */
908 if (pEASData->pVoiceMgr->workload)
909 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
910#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -0800911
Dave Sparks56c99cd2009-08-24 17:35:45 -0700912#ifdef _METRICS_ENABLED
913 /* stop performance counter */
914 if (pEASData->pMetricsData)
915 {
916 PERF_TIMER temp;
917 temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
918
919 /* if max render time, record the number of voices and time */
920 if ((*pEASData->pMetricsModule->pfRecordMaxValue)
921 (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
922 {
923 (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
924 (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
925 }
926 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800927#endif
928
929#ifdef JET_INTERFACE
Dave Sparks56c99cd2009-08-24 17:35:45 -0700930 /* let JET to do its thing */
931 if (pEASData->jetHandle != NULL)
932 {
933 result = JET_Process(pEASData);
934 if (result != EAS_SUCCESS)
935 return result;
936 }
The Android Open Source Project7df30102009-03-03 19:30:38 -0800937#endif
938
Dave Sparks56c99cd2009-08-24 17:35:45 -0700939 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800940}
941
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700942#ifdef JET_INTERFACE
The Android Open Source Project7df30102009-03-03 19:30:38 -0800943/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -0800944 * EAS_SetTransposition)
945 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -0700946 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -0800947 * Sets the key tranposition for the synthesizer. Transposes all
948 * melodic instruments by the specified amount. Range is limited
949 * to +/-12 semitones.
950 *
951 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700952 * pEASData - handle to data for this instance
953 * handle - handle to stream
954 * transposition - +/-12 semitones
955 *
The Android Open Source Project7df30102009-03-03 19:30:38 -0800956 * Outputs:
957 *
958 * Side Effects:
959 *
960 *----------------------------------------------------------------------------
961*/
962EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
963{
964
Dave Sparks56c99cd2009-08-24 17:35:45 -0700965 /* check range */
966 if ((transposition < -12) || (transposition > 12))
967 return EAS_ERROR_INVALID_PARAMETER;
The Android Open Source Project7df30102009-03-03 19:30:38 -0800968
Dave Sparks56c99cd2009-08-24 17:35:45 -0700969 if (!EAS_StreamReady(pEASData, pStream))
970 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
971 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
The Android Open Source Project7df30102009-03-03 19:30:38 -0800972}
Marco Nelissen2fa59c82020-04-22 09:33:28 -0700973#endif
Dave Sparks56c99cd2009-08-24 17:35:45 -0700974
The Android Open Source Project7df30102009-03-03 19:30:38 -0800975/*----------------------------------------------------------------------------
976 * EAS_ParseEvents()
977 *----------------------------------------------------------------------------
978 * Purpose:
979 * Parse events in the current streams until the desired time is reached.
980 *
981 * Inputs:
982 * pEASData - buffer for internal EAS data
Dave Sparks56c99cd2009-08-24 17:35:45 -0700983 * endTime - stop parsing if this time is reached
984 * parseMode - play, locate, or metadata
The Android Open Source Project7df30102009-03-03 19:30:38 -0800985 *
986 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -0700987 * EAS_SUCCESS if PCM data was successfully rendered
The Android Open Source Project7df30102009-03-03 19:30:38 -0800988 *
989 *----------------------------------------------------------------------------
990*/
991static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
992{
Dave Sparks56c99cd2009-08-24 17:35:45 -0700993 S_FILE_PARSER_INTERFACE *pParserModule;
994 EAS_RESULT result;
995 EAS_I32 parserState;
996 EAS_BOOL done;
997 EAS_INT yieldCount = YIELD_EVENT_COUNT;
998 EAS_U32 time = 0;
Phil Burk27151ca2018-08-18 11:52:03 -0700999
Phil Burkc71f73a2018-06-19 08:19:05 -07001000 // This constant is the maximum number of events that can be processed in a single time slice.
1001 // A typical ringtone will contain a few events per time slice.
1002 // Extremely dense ringtones might go up to 50 events.
1003 // If we see this many events then the file is probably stuck in an infinite loop
Phil Burk27151ca2018-08-18 11:52:03 -07001004 // and should be aborted.
1005 static const EAS_INT MAX_EVENT_COUNT = 100000;
Phil Burkc71f73a2018-06-19 08:19:05 -07001006 EAS_INT eventCount = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001007
Dave Sparks56c99cd2009-08-24 17:35:45 -07001008 /* does this parser have a time function? */
1009 pParserModule = pStream->pParserModule;
1010 if (pParserModule->pfTime == NULL)
1011 {
1012 /* check state */
1013 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
1014 return result;
1015 /* if play state, advance time */
1016 if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
1017 pStream->time += pStream->frameLength;
1018 done = EAS_TRUE;
1019 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001020
Dave Sparks56c99cd2009-08-24 17:35:45 -07001021 /* assume we're not done, in case we abort out */
1022 else
1023 {
1024 pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
1025 done = EAS_FALSE;
1026 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001027
Dave Sparks56c99cd2009-08-24 17:35:45 -07001028 while (!done)
1029 {
The Android Open Source Project7df30102009-03-03 19:30:38 -08001030
Dave Sparks56c99cd2009-08-24 17:35:45 -07001031 /* check for stopped state */
1032 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
1033 return result;
1034 if (parserState > EAS_STATE_PLAY)
1035 {
1036 /* save current time if we're not in play mode */
1037 if (parseMode != eParserModePlay)
1038 pStream->time = time << 8;
1039 done = EAS_TRUE;
1040 break;
1041 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001042
Dave Sparks56c99cd2009-08-24 17:35:45 -07001043 /* get the next event time */
1044 if (pParserModule->pfTime)
1045 {
1046 if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
1047 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001048
Dave Sparks56c99cd2009-08-24 17:35:45 -07001049 /* if next event is within this frame, parse it */
1050 if (time < (endTime >> 8))
1051 {
The Android Open Source Project7df30102009-03-03 19:30:38 -08001052
Dave Sparks56c99cd2009-08-24 17:35:45 -07001053 /* parse the next event */
Phil Burkc71f73a2018-06-19 08:19:05 -07001054 if (pParserModule->pfEvent) {
1055 if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode))
1056 != EAS_SUCCESS) {
1057 ALOGE("%s() pfEvent returned %ld", __func__, result);
Dave Sparks56c99cd2009-08-24 17:35:45 -07001058 return result;
Phil Burkc71f73a2018-06-19 08:19:05 -07001059 }
1060 }
Phil Burk27151ca2018-08-18 11:52:03 -07001061
1062 // An infinite loop within a ringtone file can cause this function
Phil Burkc71f73a2018-06-19 08:19:05 -07001063 // to loop forever. Try to detect that and return an error.
Phil Burk27151ca2018-08-18 11:52:03 -07001064 // Only check when playing. Otherwise a very large file could be rejected
1065 // when scanning the entire file in a single call to this function.
1066 // OTA files will only do infinite loops when in eParserModePlay.
1067 if (++eventCount >= MAX_EVENT_COUNT && parseMode == eParserModePlay) {
1068 ALOGE("%s() aborting, %d events. Infinite loop in song file?!",
Phil Burkc71f73a2018-06-19 08:19:05 -07001069 __func__, eventCount);
1070 android_errorWriteLog(0x534e4554, "68664359");
1071 return EAS_ERROR_FILE_POS;
1072 }
Dave Sparks56c99cd2009-08-24 17:35:45 -07001073 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001074
Dave Sparks56c99cd2009-08-24 17:35:45 -07001075 /* no more events in this frame, advance time */
1076 else
1077 {
1078 pStream->time = endTime;
1079 done = EAS_TRUE;
1080 }
1081 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001082
Dave Sparks56c99cd2009-08-24 17:35:45 -07001083 /* check for max workload exceeded */
1084 if (VMCheckWorkload(pEASData->pVoiceMgr))
1085 {
1086 /* stop even though we may not have parsed
1087 * all the events in this frame. The parser will try to
1088 * catch up on the next frame.
1089 */
1090 break;
1091 }
1092
1093 /* give host a chance for an early abort */
1094 if (--yieldCount == 0)
1095 {
1096 if (EAS_HWYield(pEASData->hwInstData))
1097 break;
1098 yieldCount = YIELD_EVENT_COUNT;
1099 }
1100 }
1101
1102 /* if no early abort, parsing is complete for this frame */
1103 if (done)
1104 pStream->streamFlags |= STREAM_FLAGS_PARSED;
1105
1106 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001107}
1108
1109/*----------------------------------------------------------------------------
1110 * EAS_ParseMetaData()
1111 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001112 * Purpose:
1113 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001114 *
1115 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001116 * pEASData - pointer to overall EAS data structure
1117 * handle - file or stream handle
1118 * playLength - pointer to variable to store the play length (in msecs)
1119 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001120 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001121 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001122 *
1123 * Side Effects:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001124 * - resets the parser to the start of the file
The Android Open Source Project7df30102009-03-03 19:30:38 -08001125 *----------------------------------------------------------------------------
1126*/
1127EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
1128{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001129 S_FILE_PARSER_INTERFACE *pParserModule;
1130 EAS_RESULT result;
1131 EAS_STATE state;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001132
Dave Sparks56c99cd2009-08-24 17:35:45 -07001133 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1134 if (pParserModule == NULL)
1135 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001136
Dave Sparks56c99cd2009-08-24 17:35:45 -07001137 /* check parser state */
1138 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
1139 return result;
1140 if (state >= EAS_STATE_OPEN)
1141 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001142
Dave Sparks56c99cd2009-08-24 17:35:45 -07001143 /* if parser has metadata function, use that */
1144 if (pParserModule->pfGetMetaData != NULL)
1145 return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001146
Dave Sparks56c99cd2009-08-24 17:35:45 -07001147 /* reset the parser to the beginning */
1148 if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
1149 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001150
Dave Sparks56c99cd2009-08-24 17:35:45 -07001151 /* parse the file to end */
1152 pStream->time = 0;
1153 VMInitWorkload(pEASData->pVoiceMgr);
1154 if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
1155 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001156
Dave Sparks56c99cd2009-08-24 17:35:45 -07001157 /* get the parser time */
1158 if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
1159 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001160
Dave Sparks56c99cd2009-08-24 17:35:45 -07001161 /* reset the parser to the beginning */
1162 pStream->time = 0;
1163 return (*pParserModule->pfReset)(pEASData, pStream->handle);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001164}
1165
1166/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001167 * EAS_CloseFile()
1168 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001169 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001170 * Closes an audio file or stream. Playback should have either paused or
1171 * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
1172 *
1173 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001174 * pEASData - pointer to overall EAS data structure
1175 * handle - file or stream handle
1176 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001177 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001178 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001179 *
1180 * Side Effects:
1181 *
1182 *----------------------------------------------------------------------------
1183*/
1184EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1185{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001186 S_FILE_PARSER_INTERFACE *pParserModule;
1187 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001188
Dave Sparks56c99cd2009-08-24 17:35:45 -07001189 /* call the close function */
1190 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1191 if (pParserModule == NULL)
1192 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001193
Dave Sparks56c99cd2009-08-24 17:35:45 -07001194 result = (*pParserModule->pfClose)(pEASData, pStream->handle);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001195
Dave Sparks56c99cd2009-08-24 17:35:45 -07001196 /* clear the handle and parser interface pointer */
1197 pStream->handle = NULL;
1198 pStream->pParserModule = NULL;
1199 return result;
1200}
The Android Open Source Project7df30102009-03-03 19:30:38 -08001201
1202/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001203 * EAS_State()
1204 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001205 * Purpose:
1206 * Returns the state of an audio file or stream.
The Android Open Source Project7df30102009-03-03 19:30:38 -08001207 *
1208 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001209 * pEASData - pointer to overall EAS data structure
1210 * handle - file or stream handle
1211 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001212 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001213 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001214 *
1215 * Side Effects:
1216 *
1217 *----------------------------------------------------------------------------
1218*/
1219EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
1220{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001221 S_FILE_PARSER_INTERFACE *pParserModule;
1222 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001223
Dave Sparks56c99cd2009-08-24 17:35:45 -07001224 /* call the parser to return state */
1225 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1226 if (pParserModule == NULL)
1227 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001228
Dave Sparks56c99cd2009-08-24 17:35:45 -07001229 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
1230 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001231
Dave Sparks56c99cd2009-08-24 17:35:45 -07001232 /* if repeat count is set for this parser, mask the stopped state from the application */
1233 if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
1234 *pState = EAS_STATE_PLAY;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001235
Marco Nelissen3e2bd1f2010-12-21 16:00:10 -08001236 /* if we're not paused or pausing, we don't need to hide state from host */
1237 if (*pState != EAS_STATE_PAUSED && *pState != EAS_STATE_PAUSING)
Dave Sparks56c99cd2009-08-24 17:35:45 -07001238 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001239
Dave Sparks56c99cd2009-08-24 17:35:45 -07001240 /* if stream is about to be paused, report it as paused */
1241 if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
1242 {
1243 if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
1244 *pState = EAS_STATE_PAUSED;
1245 else
1246 *pState = EAS_STATE_PAUSING;
1247 }
1248
1249 /* if stream is about to resume, report it as playing */
1250 if (pStream->streamFlags & STREAM_FLAGS_RESUME)
1251 *pState = EAS_STATE_PLAY;
1252
1253 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001254}
1255
1256/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001257 * EAS_SetVolume()
1258 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001259 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001260 * Set the master gain for the mix engine in 1dB increments
1261 *
1262 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001263 * pEASData - pointer to overall EAS data structure
1264 * volume - the desired master gain (100 is max)
1265 * handle - file or stream handle
1266 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001267 * Outputs:
1268 *
1269 *
1270 * Side Effects:
1271 * overrides any previously set master volume from sysex
1272 *
1273 *----------------------------------------------------------------------------
1274*/
1275EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
1276{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001277 EAS_I16 gain;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001278
Dave Sparks56c99cd2009-08-24 17:35:45 -07001279 /* check range */
1280 if ((volume < 0) || (volume > EAS_MAX_VOLUME))
1281 return EAS_ERROR_PARAMETER_RANGE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001282
Dave Sparks56c99cd2009-08-24 17:35:45 -07001283 /* stream volume */
1284 if (pStream != NULL)
1285 {
1286 EAS_I32 gainOffset;
1287 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001288
Dave Sparks56c99cd2009-08-24 17:35:45 -07001289 if (!EAS_StreamReady(pEASData, pStream))
1290 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001291
Dave Sparks56c99cd2009-08-24 17:35:45 -07001292 /* get gain offset */
1293 pStream->volume = (EAS_U8) volume;
1294 result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
1295 if (result == EAS_SUCCESS)
1296 volume += gainOffset;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001297
Dave Sparks56c99cd2009-08-24 17:35:45 -07001298 /* set stream volume */
1299 gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
1300
1301 /* convert to linear scalar */
1302 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
1303 }
1304
1305 /* master volume */
1306 pEASData->masterVolume = (EAS_U8) volume;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001307#if (NUM_OUTPUT_CHANNELS == 1)
Dave Sparks56c99cd2009-08-24 17:35:45 -07001308 /* leave 3dB headroom for mono output */
1309 volume -= 3;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001310#endif
1311
Dave Sparks56c99cd2009-08-24 17:35:45 -07001312 gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
1313 pEASData->masterGain = gain;
1314 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001315}
1316
1317/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001318 * EAS_Locate()
1319 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001320 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001321 * Locate into the file associated with the handle.
1322 *
1323 * Inputs:
1324 * pEASData - pointer to overall EAS data structure
Dave Sparks56c99cd2009-08-24 17:35:45 -07001325 * handle - file handle
1326 * milliseconds - playback offset from start of file in milliseconds
1327 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001328 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001329 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001330 *
1331 * Side Effects:
1332 * the actual offset will be quantized to the closest update period, typically
1333 * a resolution of 5.9ms. Notes that are started prior to this time will not
1334 * sound. Any notes currently playing will be shut off.
1335 *
1336 *----------------------------------------------------------------------------
1337*/
1338EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
1339{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001340 S_FILE_PARSER_INTERFACE *pParserModule;
1341 EAS_RESULT result;
1342 EAS_U32 requestedTime;
1343 EAS_STATE state;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001344
Dave Sparks56c99cd2009-08-24 17:35:45 -07001345 /* get pointer to parser function table */
1346 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1347 if (pParserModule == NULL)
1348 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001349
Dave Sparks56c99cd2009-08-24 17:35:45 -07001350 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
1351 return result;
1352 if (state >= EAS_STATE_OPEN)
1353 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001354
Dave Sparks56c99cd2009-08-24 17:35:45 -07001355 /* handle offset and limit to start of file */
1356 /*lint -e{704} use shift for performance*/
1357 if (offset)
1358 milliseconds += (EAS_I32) pStream->time >> 8;
1359 if (milliseconds < 0)
1360 milliseconds = 0;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001361
Dave Sparks56c99cd2009-08-24 17:35:45 -07001362 /* check to see if the request is different from the current time */
1363 requestedTime = (EAS_U32) milliseconds;
1364 if (requestedTime == (pStream->time >> 8))
1365 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001366
Dave Sparks56c99cd2009-08-24 17:35:45 -07001367 /* set the locate flag */
1368 pStream->streamFlags |= STREAM_FLAGS_LOCATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001369
Dave Sparks56c99cd2009-08-24 17:35:45 -07001370 /* use the parser locate function, if available */
1371 if (pParserModule->pfLocate != NULL)
1372 {
1373 EAS_BOOL parserLocate = EAS_FALSE;
1374 result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
1375 if (!parserLocate)
1376 {
1377 if (result == EAS_SUCCESS)
1378 pStream->time = requestedTime << 8;
1379 return result;
1380 }
1381 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001382
Dave Sparks56c99cd2009-08-24 17:35:45 -07001383 /* if we were paused and not going to resume, set pause request flag */
1384 if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
1385 pStream->streamFlags |= STREAM_FLAGS_PAUSE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001386
Dave Sparks56c99cd2009-08-24 17:35:45 -07001387 /* reset the synth and parser */
1388 if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
1389 return result;
1390 pStream->time = 0;
1391
1392 /* locating forward, clear parsed flag and parse data until we get to the requested location */
1393 if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
1394 return result;
1395
1396 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001397}
1398
1399/*----------------------------------------------------------------------------
1400 * EAS_GetLocation()
1401 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001402 * Purpose:
1403 * Returns the current playback offset
The Android Open Source Project7df30102009-03-03 19:30:38 -08001404 *
1405 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001406 * pEASData - pointer to overall EAS data structure
1407 * handle - file handle
1408 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001409 * Outputs:
1410 * The offset in milliseconds from the start of the current sequence, quantized
1411 * to the nearest update period. Actual resolution is typically 5.9 ms.
1412 *
1413 * Side Effects:
1414 *
1415 *----------------------------------------------------------------------------
1416*/
1417/*lint -esym(715, pEASData) reserved for future use */
1418EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
1419{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001420 if (!EAS_StreamReady(pEASData, pStream))
1421 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001422
Dave Sparks56c99cd2009-08-24 17:35:45 -07001423 *pTime = pStream->time >> 8;
1424 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001425}
1426
Marco Nelissen2fa59c82020-04-22 09:33:28 -07001427#ifdef JET_INTERFACE
The Android Open Source Project7df30102009-03-03 19:30:38 -08001428/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001429 * EAS_Pause()
1430 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001431 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001432 * Pauses the playback of the data associated with this handle. The audio
1433 * is gracefully ramped down to prevent clicks and pops. It may take several
1434 * buffers of audio before the audio is muted.
1435 *
1436 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001437 * psEASData - pointer to overall EAS data structure
1438 * handle - file or stream handle
1439 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001440 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001441 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001442 *
1443 * Side Effects:
1444 *
1445 *
1446 *----------------------------------------------------------------------------
1447*/
1448EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1449{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001450 S_FILE_PARSER_INTERFACE *pParserModule;
1451 EAS_STATE state;
1452 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001453
Dave Sparks56c99cd2009-08-24 17:35:45 -07001454 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1455 if (pParserModule == NULL)
1456 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001457
Dave Sparks56c99cd2009-08-24 17:35:45 -07001458 /* check for valid state */
1459 result = pParserModule->pfState(pEASData, pStream->handle, &state);
1460 if (result == EAS_SUCCESS)
1461 {
1462 if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
1463 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001464
Dave Sparks56c99cd2009-08-24 17:35:45 -07001465 /* make sure parser implements pause */
1466 if (pParserModule->pfPause == NULL)
1467 result = EAS_ERROR_NOT_IMPLEMENTED;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001468
Dave Sparks56c99cd2009-08-24 17:35:45 -07001469 /* clear resume flag */
1470 pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001471
Dave Sparks56c99cd2009-08-24 17:35:45 -07001472 /* set pause flag */
1473 pStream->streamFlags |= STREAM_FLAGS_PAUSE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001474
Dave Sparks56c99cd2009-08-24 17:35:45 -07001475#if 0
1476 /* pause the stream */
1477 if (pParserModule->pfPause)
1478 result = pParserModule->pfPause(pEASData, pStream->handle);
1479 else
1480 result = EAS_ERROR_NOT_IMPLEMENTED;
1481#endif
1482 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001483
Dave Sparks56c99cd2009-08-24 17:35:45 -07001484 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001485}
1486
1487/*----------------------------------------------------------------------------
1488 * EAS_Resume()
1489 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001490 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001491 * Resumes the playback of the data associated with this handle. The audio
1492 * is gracefully ramped up to prevent clicks and pops.
1493 *
1494 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001495 * psEASData - pointer to overall EAS data structure
1496 * handle - file or stream handle
1497 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001498 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001499 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001500 *
1501 * Side Effects:
1502 *
1503 *
1504 *----------------------------------------------------------------------------
1505*/
1506EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1507{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001508 S_FILE_PARSER_INTERFACE *pParserModule;
1509 EAS_STATE state;
1510 EAS_RESULT result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001511
Dave Sparks56c99cd2009-08-24 17:35:45 -07001512 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1513 if (pParserModule == NULL)
1514 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001515
Dave Sparks56c99cd2009-08-24 17:35:45 -07001516 /* check for valid state */
1517 result = pParserModule->pfState(pEASData, pStream->handle, &state);
1518 if (result == EAS_SUCCESS)
1519 {
1520 if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
1521 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001522
Dave Sparks56c99cd2009-08-24 17:35:45 -07001523 /* make sure parser implements this function */
1524 if (pParserModule->pfResume == NULL)
1525 result = EAS_ERROR_NOT_IMPLEMENTED;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001526
Dave Sparks56c99cd2009-08-24 17:35:45 -07001527 /* clear pause flag */
1528 pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001529
Dave Sparks56c99cd2009-08-24 17:35:45 -07001530 /* set resume flag */
1531 pStream->streamFlags |= STREAM_FLAGS_RESUME;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001532
Dave Sparks56c99cd2009-08-24 17:35:45 -07001533#if 0
1534 /* resume the stream */
1535 if (pParserModule->pfResume)
1536 result = pParserModule->pfResume(pEASData, pStream->handle);
1537 else
1538 result = EAS_ERROR_NOT_IMPLEMENTED;
1539#endif
1540 }
The Android Open Source Project7df30102009-03-03 19:30:38 -08001541
Dave Sparks56c99cd2009-08-24 17:35:45 -07001542 return result;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001543}
Marco Nelissen2fa59c82020-04-22 09:33:28 -07001544#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -08001545
1546/*----------------------------------------------------------------------------
The Android Open Source Project7df30102009-03-03 19:30:38 -08001547 * EAS_SetParameter()
1548 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001549 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001550 * Set the parameter of a module. See E_MODULES for a list of modules
1551 * and the header files of the modules for a list of parameters.
1552 *
1553 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001554 * psEASData - pointer to overall EAS data structure
1555 * handle - file or stream handle
1556 * module - enumerated module number
1557 * param - enumerated parameter number
1558 * value - new parameter value
1559 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001560 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001561 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001562 *
1563 * Side Effects:
1564 *
1565 *
1566 *----------------------------------------------------------------------------
1567*/
1568EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
1569{
1570
Dave Sparks56c99cd2009-08-24 17:35:45 -07001571 if (module >= NUM_EFFECTS_MODULES)
1572 return EAS_ERROR_INVALID_MODULE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001573
Dave Sparks56c99cd2009-08-24 17:35:45 -07001574 if (pEASData->effectsModules[module].effectData == NULL)
1575 return EAS_ERROR_INVALID_MODULE;
1576
1577 return (*pEASData->effectsModules[module].effect->pFSetParam)
1578 (pEASData->effectsModules[module].effectData, param, value);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001579}
1580
Dave Sparks56c99cd2009-08-24 17:35:45 -07001581#ifdef _METRICS_ENABLED
The Android Open Source Project7df30102009-03-03 19:30:38 -08001582/*----------------------------------------------------------------------------
1583 * EAS_MetricsReport()
1584 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001585 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001586 * Displays the current metrics through the metrics interface.
1587 *
1588 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001589 * p - instance data handle
1590 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001591 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001592 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001593 *
1594 * Side Effects:
1595 *
1596 *----------------------------------------------------------------------------
1597*/
1598EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
1599{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001600 if (!pEASData->pMetricsModule)
1601 return EAS_ERROR_INVALID_MODULE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001602
Dave Sparks56c99cd2009-08-24 17:35:45 -07001603 return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001604}
1605
1606/*----------------------------------------------------------------------------
1607 * EAS_MetricsReset()
1608 *----------------------------------------------------------------------------
Dave Sparks56c99cd2009-08-24 17:35:45 -07001609 * Purpose:
The Android Open Source Project7df30102009-03-03 19:30:38 -08001610 * Resets the metrics.
1611 *
1612 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001613 * p - instance data handle
1614 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001615 * Outputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001616 *
The Android Open Source Project7df30102009-03-03 19:30:38 -08001617 *
1618 * Side Effects:
1619 *
1620 *----------------------------------------------------------------------------
1621*/
1622EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
1623{
1624
Dave Sparks56c99cd2009-08-24 17:35:45 -07001625 if (!pEASData->pMetricsModule)
1626 return EAS_ERROR_INVALID_MODULE;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001627
Dave Sparks56c99cd2009-08-24 17:35:45 -07001628 return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
The Android Open Source Project7df30102009-03-03 19:30:38 -08001629}
1630#endif
1631
Marco Nelissenaf415952020-03-20 17:08:03 -07001632#ifdef FILE_HEADER_SEARCH
The Android Open Source Project7df30102009-03-03 19:30:38 -08001633/*----------------------------------------------------------------------------
1634 * EAS_SearchFile
1635 *----------------------------------------------------------------------------
1636 * Search file for specific sequence starting at current file
1637 * position. Returns offset to start of sequence.
1638 *
1639 * Inputs:
Dave Sparks56c99cd2009-08-24 17:35:45 -07001640 * pEASData - pointer to EAS persistent data object
1641 * fileHandle - file handle
1642 * searchString - pointer to search sequence
1643 * len - length of search sequence
1644 * pOffset - pointer to variable to store offset to sequence
The Android Open Source Project7df30102009-03-03 19:30:38 -08001645 *
1646 * Returns EAS_EOF if end-of-file is reached
1647 *----------------------------------------------------------------------------
1648*/
1649EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
1650{
Dave Sparks56c99cd2009-08-24 17:35:45 -07001651 EAS_RESULT result;
1652 EAS_INT index;
1653 EAS_U8 c;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001654
Dave Sparks56c99cd2009-08-24 17:35:45 -07001655 *pOffset = -1;
1656 index = 0;
1657 for (;;)
1658 {
1659 result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
1660 if (result != EAS_SUCCESS)
1661 return result;
1662 if (c == searchString[index])
1663 {
1664 index++;
1665 if (index == 4)
1666 {
1667 result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
1668 if (result != EAS_SUCCESS)
1669 return result;
1670 *pOffset -= len;
1671 break;
1672 }
1673 }
1674 else
1675 index = 0;
1676 }
1677 return EAS_SUCCESS;
The Android Open Source Project7df30102009-03-03 19:30:38 -08001678}
Marco Nelissenaf415952020-03-20 17:08:03 -07001679#endif
The Android Open Source Project7df30102009-03-03 19:30:38 -08001680
1681