1 /*----------------------------------------------------------------------------
2 *
3 * File:
4 * eas_public.c
5 *
6 * Contents and purpose:
7 * Contains EAS library public interface
8 *
9 * 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
30 #include "eas_synthcfg.h"
31 #include "eas.h"
32 #include "eas_config.h"
33 #include "eas_host.h"
34 #include "eas_report.h"
35 #include "eas_data.h"
36 #include "eas_parser.h"
37 #include "eas_pcm.h"
38 #include "eas_midi.h"
39 #include "eas_mixer.h"
40 #include "eas_build.h"
41 #include "eas_vm_protos.h"
42 #include "eas_math.h"
43
44 #ifdef JET_INTERFACE
45 #include "jet_data.h"
46 #endif
47
48 #ifdef DLS_SYNTHESIZER
49 #include "eas_mdls.h"
50 #endif
51
52 /* number of events to parse before calling EAS_HWYield function */
53 #define YIELD_EVENT_COUNT 10
54
55 /*----------------------------------------------------------------------------
56 * easLibConfig
57 *
58 * This structure is available through the EAS public interface to allow
59 * the user to check the configuration of the library.
60 *----------------------------------------------------------------------------
61 */
62 static const S_EAS_LIB_CONFIG easLibConfig =
63 {
64 LIB_VERSION,
65 #ifdef _CHECKED_BUILD
66 EAS_TRUE,
67 #else
68 EAS_FALSE,
69 #endif
70 MAX_SYNTH_VOICES,
71 NUM_OUTPUT_CHANNELS,
72 _OUTPUT_SAMPLE_RATE,
73 BUFFER_SIZE_IN_MONO_SAMPLES,
74 #ifdef _FILTER_ENABLED
75 EAS_TRUE,
76 #else
77 EAS_FALSE,
78 #endif
79 _BUILD_TIME_,
80 _BUILD_VERSION_
81 };
82
83 /* local prototypes */
84 static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, S_EAS_STREAM *pStream, EAS_U32 endTime, EAS_INT parseMode);
85
86 /*----------------------------------------------------------------------------
87 * EAS_SetStreamParameter
88 *----------------------------------------------------------------------------
89 * Sets the specified parameter in the stream. Allows access to
90 * customizable settings within the individual file parsers.
91 *----------------------------------------------------------------------------
92 * pEASData - pointer to EAS persistent data object
93 * pStream - stream handle
94 * param - enumerated parameter (see eas_parser.h)
95 * value - new value
96 *----------------------------------------------------------------------------
97 */
EAS_SetStreamParameter(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_I32 param,EAS_I32 value)98 EAS_RESULT EAS_SetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 value)
99 {
100 S_FILE_PARSER_INTERFACE *pParserModule;
101
102 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
103 if (pParserModule->pfSetData)
104 return (*pParserModule->pfSetData)(pEASData, pStream->handle, param, value);
105 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
106 }
107
108 /*----------------------------------------------------------------------------
109 * EAS_GetStreamParameter
110 *----------------------------------------------------------------------------
111 * Sets the specified parameter in the stream. Allows access to
112 * customizable settings within the individual file parsers.
113 *----------------------------------------------------------------------------
114 * pEASData - pointer to EAS persistent data object
115 * pStream - stream handle
116 * param - enumerated parameter (see eas_parser.h)
117 * pValue - pointer to variable to receive current setting
118 *----------------------------------------------------------------------------
119 */
EAS_GetStreamParameter(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_I32 param,EAS_I32 * pValue)120 EAS_RESULT EAS_GetStreamParameter (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 param, EAS_I32 *pValue)
121 {
122 S_FILE_PARSER_INTERFACE *pParserModule;
123
124 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
125 if (pParserModule->pfGetData)
126 return (*pParserModule->pfGetData)(pEASData, pStream->handle, param, pValue);
127 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
128 }
129
130 /*----------------------------------------------------------------------------
131 * EAS_StreamReady()
132 *----------------------------------------------------------------------------
133 * This routine sets common parameters like transpose, volume, etc.
134 * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
135 * fails, it attempts to get the synth handle from the parser and
136 * set the parameter directly on the synth. This eliminates duplicate
137 * code in the parser.
138 *----------------------------------------------------------------------------
139 */
EAS_StreamReady(S_EAS_DATA * pEASData,EAS_HANDLE pStream)140 EAS_BOOL EAS_StreamReady (S_EAS_DATA *pEASData, EAS_HANDLE pStream)
141 {
142 S_FILE_PARSER_INTERFACE *pParserModule;
143 EAS_STATE state;
144
145 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
146 if (pParserModule->pfState(pEASData, pStream->handle, &state) != EAS_SUCCESS)
147 return EAS_FALSE;
148 return (state < EAS_STATE_OPEN);
149 }
150
151 /*----------------------------------------------------------------------------
152 * EAS_IntSetStrmParam()
153 *----------------------------------------------------------------------------
154 * This routine sets common parameters like transpose, volume, etc.
155 * First, it attempts to use the parser EAS_SetStreamParameter interface. If that
156 * fails, it attempts to get the synth handle from the parser and
157 * set the parameter directly on the synth. This eliminates duplicate
158 * code in the parser.
159 *----------------------------------------------------------------------------
160 */
EAS_IntSetStrmParam(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_INT param,EAS_I32 value)161 EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value)
162 {
163 S_SYNTH *pSynth;
164
165 /* try to set the parameter using stream interface */
166 if (EAS_SetStreamParameter(pEASData, pStream, param, value) == EAS_SUCCESS)
167 return EAS_SUCCESS;
168
169 /* get a pointer to the synth object and set it directly */
170 /*lint -e{740} we are cheating by passing a pointer through this interface */
171 if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
172 return EAS_ERROR_INVALID_PARAMETER;
173
174 if (pSynth == NULL)
175 return EAS_ERROR_INVALID_PARAMETER;
176
177 switch (param)
178 {
179
180 #ifdef DLS_SYNTHESIZER
181 case PARSER_DATA_DLS_COLLECTION:
182 {
183 EAS_RESULT result = VMSetDLSLib(pSynth, (EAS_DLSLIB_HANDLE) value);
184 if (result == EAS_SUCCESS)
185 {
186 DLSAddRef((S_DLS*) value);
187 VMInitializeAllChannels(pEASData->pVoiceMgr, pSynth);
188 }
189 return result;
190 }
191 #endif
192
193 case PARSER_DATA_EAS_LIBRARY:
194 return VMSetEASLib(pSynth, (EAS_SNDLIB_HANDLE) value);
195
196 case PARSER_DATA_POLYPHONY:
197 return VMSetPolyphony(pEASData->pVoiceMgr, pSynth, value);
198
199 case PARSER_DATA_PRIORITY:
200 return VMSetPriority(pEASData->pVoiceMgr, pSynth, value);
201
202 case PARSER_DATA_TRANSPOSITION:
203 VMSetTranposition(pSynth, value);
204 break;
205
206 case PARSER_DATA_VOLUME:
207 VMSetVolume(pSynth, (EAS_U16) value);
208 break;
209
210 default:
211 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
212 return EAS_ERROR_INVALID_PARAMETER;
213 }
214
215 return EAS_SUCCESS;
216 }
217
218 /*----------------------------------------------------------------------------
219 * EAS_IntGetStrmParam()
220 *----------------------------------------------------------------------------
221 * This routine gets common parameters like transpose, volume, etc.
222 * First, it attempts to use the parser EAS_GetStreamParameter interface. If that
223 * fails, it attempts to get the synth handle from the parser and
224 * get the parameter directly on the synth.
225 *----------------------------------------------------------------------------
226 */
EAS_IntGetStrmParam(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_INT param,EAS_I32 * pValue)227 EAS_RESULT EAS_IntGetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 *pValue)
228 {
229 S_SYNTH *pSynth;
230
231 /* try to set the parameter */
232 if (EAS_GetStreamParameter(pEASData, pStream, param, pValue) == EAS_SUCCESS)
233 return EAS_SUCCESS;
234
235 /* get a pointer to the synth object and retrieve data directly */
236 /*lint -e{740} we are cheating by passing a pointer through this interface */
237 if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
238 return EAS_ERROR_INVALID_PARAMETER;
239
240 if (pSynth == NULL)
241 return EAS_ERROR_INVALID_PARAMETER;
242
243 switch (param)
244 {
245 case PARSER_DATA_POLYPHONY:
246 return VMGetPolyphony(pEASData->pVoiceMgr, pSynth, pValue);
247
248 case PARSER_DATA_PRIORITY:
249 return VMGetPriority(pEASData->pVoiceMgr, pSynth, pValue);
250
251 case PARSER_DATA_TRANSPOSITION:
252 VMGetTranposition(pSynth, pValue);
253 break;
254
255 case PARSER_DATA_NOTE_COUNT:
256 *pValue = VMGetNoteCount(pSynth);
257 break;
258
259 default:
260 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Invalid paramter %d in call to EAS_IntSetStrmParam", param); */ }
261 return EAS_ERROR_INVALID_PARAMETER;
262 }
263
264 return EAS_SUCCESS;
265 }
266
267 /*----------------------------------------------------------------------------
268 * EAS_AllocateStream()
269 *----------------------------------------------------------------------------
270 * Purpose:
271 * Allocates a stream handle
272 *
273 * Inputs:
274 *
275 * Outputs:
276 *
277 *----------------------------------------------------------------------------
278 */
EAS_AllocateStream(EAS_DATA_HANDLE pEASData)279 static EAS_INT EAS_AllocateStream (EAS_DATA_HANDLE pEASData)
280 {
281 EAS_INT streamNum;
282
283 /* check for static allocation, only one stream allowed */
284 if (pEASData->staticMemoryModel)
285 {
286 if (pEASData->streams[0].handle != NULL)
287 {
288 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Attempt to open multiple streams in static model\n"); */ }
289 return -1;
290 }
291 return 0;
292 }
293
294 /* dynamic model */
295 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
296 if (pEASData->streams[streamNum].handle == NULL)
297 break;
298 if (streamNum == MAX_NUMBER_STREAMS)
299 {
300 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Exceeded maximum number of open streams\n"); */ }
301 return -1;
302 }
303 return streamNum;
304 }
305
306 /*----------------------------------------------------------------------------
307 * EAS_InitStream()
308 *----------------------------------------------------------------------------
309 * Purpose:
310 * Initialize a stream
311 *
312 * Inputs:
313 *
314 * Outputs:
315 *
316 *----------------------------------------------------------------------------
317 */
EAS_InitStream(S_EAS_STREAM * pStream,EAS_VOID_PTR pParserModule,EAS_VOID_PTR streamHandle)318 static void EAS_InitStream (S_EAS_STREAM *pStream, EAS_VOID_PTR pParserModule, EAS_VOID_PTR streamHandle)
319 {
320 pStream->pParserModule = pParserModule;
321 pStream->handle = streamHandle;
322 pStream->time = 0;
323 pStream->frameLength = AUDIO_FRAME_LENGTH;
324 pStream->repeatCount = 0;
325 pStream->volume = DEFAULT_STREAM_VOLUME;
326 }
327
328 /*----------------------------------------------------------------------------
329 * EAS_Config()
330 *----------------------------------------------------------------------------
331 * Purpose:
332 * Returns a pointer to a structure containing the configuration options
333 * in this library build.
334 *
335 * Inputs:
336 *
337 * Outputs:
338 *
339 *----------------------------------------------------------------------------
340 */
EAS_Config(void)341 EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void)
342 {
343 return &easLibConfig;
344 }
345
346 /*----------------------------------------------------------------------------
347 * EAS_Init()
348 *----------------------------------------------------------------------------
349 * Purpose:
350 * Initialize the synthesizer library
351 *
352 * Inputs:
353 * ppEASData - pointer to data handle variable for this instance
354 *
355 * Outputs:
356 *
357 *----------------------------------------------------------------------------
358 */
EAS_Init(EAS_DATA_HANDLE * ppEASData)359 EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData)
360 {
361 EAS_HW_DATA_HANDLE pHWInstData;
362 EAS_RESULT result;
363 S_EAS_DATA *pEASData;
364 EAS_INT module;
365 EAS_BOOL staticMemoryModel;
366
367 /* get the memory model */
368 staticMemoryModel = EAS_CMStaticMemoryModel();
369
370 /* initialize the host wrapper interface */
371 *ppEASData = NULL;
372 if ((result = EAS_HWInit(&pHWInstData)) != EAS_SUCCESS)
373 return result;
374
375 /* check Configuration Module for S_EAS_DATA allocation */
376 if (staticMemoryModel)
377 pEASData = EAS_CMEnumData(EAS_CM_EAS_DATA);
378 else
379 pEASData = EAS_HWMalloc(pHWInstData, sizeof(S_EAS_DATA));
380 if (!pEASData)
381 {
382 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate EAS library memory\n"); */ }
383 return EAS_ERROR_MALLOC_FAILED;
384 }
385
386 /* initialize some data */
387 EAS_HWMemSet(pEASData, 0, sizeof(S_EAS_DATA));
388 pEASData->staticMemoryModel = (EAS_BOOL8) staticMemoryModel;
389 pEASData->hwInstData = pHWInstData;
390 pEASData->renderTime = 0;
391
392 /* set header search flag */
393 #ifdef FILE_HEADER_SEARCH
394 pEASData->searchHeaderFlag = EAS_TRUE;
395 #endif
396
397 /* initalize parameters */
398 EAS_SetVolume(pEASData, NULL, DEFAULT_VOLUME);
399
400 #ifdef _METRICS_ENABLED
401 /* initalize the metrics module */
402 pEASData->pMetricsModule = EAS_CMEnumOptModules(EAS_MODULE_METRICS);
403 if (pEASData->pMetricsModule != NULL)
404 {
405 if ((result = (*pEASData->pMetricsModule->pfInit)(pEASData, &pEASData->pMetricsData)) != EAS_SUCCESS)
406 {
407 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld initializing metrics module\n", result); */ }
408 return result;
409 }
410 }
411 #endif
412
413 /* initailize the voice manager & synthesizer */
414 if ((result = VMInitialize(pEASData)) != EAS_SUCCESS)
415 return result;
416
417 /* initialize mix engine */
418 if ((result = EAS_MixEngineInit(pEASData)) != EAS_SUCCESS)
419 {
420 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld starting up mix engine\n", result); */ }
421 return result;
422 }
423
424 /* initialize effects modules */
425 for (module = 0; module < NUM_EFFECTS_MODULES; module++)
426 {
427 pEASData->effectsModules[module].effect = EAS_CMEnumFXModules(module);
428 if (pEASData->effectsModules[module].effect != NULL)
429 {
430 if ((result = (*pEASData->effectsModules[module].effect->pfInit)(pEASData, &pEASData->effectsModules[module].effectData)) != EAS_SUCCESS)
431 {
432 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Initialization of effects module %d returned %d\n", module, result); */ }
433 return result;
434 }
435 }
436 }
437
438 /* initialize PCM engine */
439 if ((result = EAS_PEInit(pEASData)) != EAS_SUCCESS)
440 {
441 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_PEInit failed with error code %ld\n", result); */ }
442 return result;
443 }
444
445 /* return instance data pointer to host */
446 *ppEASData = pEASData;
447
448 return EAS_SUCCESS;
449 }
450
451 /*----------------------------------------------------------------------------
452 * EAS_Shutdown()
453 *----------------------------------------------------------------------------
454 * Purpose:
455 * Shuts down the library. Deallocates any memory associated with the
456 * synthesizer (dynamic memory model only)
457 *
458 * Inputs:
459 * pEASData - handle to data for this instance
460 *
461 * Outputs:
462 *
463 *----------------------------------------------------------------------------
464 */
EAS_Shutdown(EAS_DATA_HANDLE pEASData)465 EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData)
466 {
467 EAS_HW_DATA_HANDLE hwInstData;
468 EAS_RESULT result, reportResult;
469 EAS_INT i;
470
471 /* establish pointers */
472 hwInstData = pEASData->hwInstData;
473
474 /* check for NULL handle */
475 if (!pEASData)
476 return EAS_ERROR_HANDLE_INTEGRITY;
477
478 /* if there are streams open, close them */
479 reportResult = EAS_SUCCESS;
480 for (i = 0; i < MAX_NUMBER_STREAMS; i++)
481 {
482 if (pEASData->streams[i].pParserModule && pEASData->streams[i].handle)
483 {
484 if ((result = (*((S_FILE_PARSER_INTERFACE*)(pEASData->streams[i].pParserModule))->pfClose)(pEASData, pEASData->streams[i].handle)) != EAS_SUCCESS)
485 {
486 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down parser module\n", result); */ }
487 reportResult = result;
488 }
489 }
490 }
491
492 /* shutdown PCM engine */
493 if ((result = EAS_PEShutdown(pEASData)) != EAS_SUCCESS)
494 {
495 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down PCM engine\n", result); */ }
496 if (reportResult == EAS_SUCCESS)
497 reportResult = result;
498 }
499
500 /* shutdown mix engine */
501 if ((result = EAS_MixEngineShutdown(pEASData)) != EAS_SUCCESS)
502 {
503 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down mix engine\n", result); */ }
504 if (reportResult == EAS_SUCCESS)
505 reportResult = result;
506 }
507
508 /* shutdown effects modules */
509 for (i = 0; i < NUM_EFFECTS_MODULES; i++)
510 {
511 if (pEASData->effectsModules[i].effect)
512 {
513 if ((result = (*pEASData->effectsModules[i].effect->pfShutdown)(pEASData, pEASData->effectsModules[i].effectData)) != EAS_SUCCESS)
514 {
515 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Shutdown of effects module %d returned %d\n", i, result); */ }
516 if (reportResult == EAS_SUCCESS)
517 reportResult = result;
518 }
519 }
520 }
521
522 /* shutdown the voice manager & synthesizer */
523 VMShutdown(pEASData);
524
525 #ifdef _METRICS_ENABLED
526 /* shutdown the metrics module */
527 if (pEASData->pMetricsModule != NULL)
528 {
529 if ((result = (*pEASData->pMetricsModule->pfShutdown)(pEASData, pEASData->pMetricsData)) != EAS_SUCCESS)
530 {
531 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down metrics module\n", result); */ }
532 if (reportResult == EAS_SUCCESS)
533 reportResult = result;
534 }
535 }
536 #endif
537
538 /* release allocated memory */
539 if (!pEASData->staticMemoryModel)
540 EAS_HWFree(hwInstData, pEASData);
541
542 /* shutdown host wrappers */
543 if (hwInstData)
544 {
545 if ((result = EAS_HWShutdown(hwInstData)) != EAS_SUCCESS)
546 {
547 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %ld shutting down host wrappers\n", result); */ }
548 if (reportResult == EAS_SUCCESS)
549 reportResult = result;
550 }
551 }
552
553 return reportResult;
554 }
555
556 #ifdef JET_INTERFACE
557 /*----------------------------------------------------------------------------
558 * EAS_OpenJETStream()
559 *----------------------------------------------------------------------------
560 * Private interface for JET to open an SMF stream with an offset
561 *----------------------------------------------------------------------------
562 */
EAS_OpenJETStream(EAS_DATA_HANDLE pEASData,EAS_FILE_HANDLE fileHandle,EAS_I32 offset,EAS_HANDLE * ppStream)563 EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream)
564 {
565 EAS_RESULT result;
566 EAS_VOID_PTR streamHandle;
567 S_FILE_PARSER_INTERFACE *pParserModule;
568 EAS_INT streamNum;
569
570 /* allocate a stream */
571 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
572 return EAS_ERROR_MAX_STREAMS_OPEN;
573
574 /* check Configuration Module for SMF parser */
575 *ppStream = NULL;
576 streamHandle = NULL;
577 pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(0);
578 if (pParserModule == NULL)
579 return EAS_ERROR_UNRECOGNIZED_FORMAT;
580
581 /* see if SMF parser recognizes the file */
582 if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, offset)) != EAS_SUCCESS)
583 {
584 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
585 return result;
586 }
587
588 /* parser recognized the file, return the handle */
589 if (streamHandle)
590 {
591 EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
592 *ppStream = &pEASData->streams[streamNum];
593 return EAS_SUCCESS;
594 }
595
596 return EAS_ERROR_UNRECOGNIZED_FORMAT;
597 }
598 #endif
599
600 /*----------------------------------------------------------------------------
601 * EAS_OpenFile()
602 *----------------------------------------------------------------------------
603 * Purpose:
604 * Opens a file for audio playback.
605 *
606 * Inputs:
607 * pEASData - pointer to overall EAS data structure
608 * pHandle - pointer to file handle
609 *
610 * Outputs:
611 *
612 *
613 * Side Effects:
614 *
615 *----------------------------------------------------------------------------
616 */
EAS_OpenFile(EAS_DATA_HANDLE pEASData,EAS_FILE_LOCATOR locator,EAS_HANDLE * ppStream)617 EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
618 {
619 EAS_RESULT result;
620 EAS_FILE_HANDLE fileHandle;
621 EAS_VOID_PTR streamHandle;
622 S_FILE_PARSER_INTERFACE *pParserModule;
623 EAS_INT streamNum;
624 EAS_INT moduleNum;
625
626 /* open the file */
627 if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
628 return result;
629
630 /* allocate a stream */
631 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
632 return EAS_ERROR_MAX_STREAMS_OPEN;
633
634 /* check Configuration Module for file parsers */
635 pParserModule = NULL;
636 *ppStream = NULL;
637 streamHandle = NULL;
638 for (moduleNum = 0; ; moduleNum++)
639 {
640 pParserModule = (S_FILE_PARSER_INTERFACE *) EAS_CMEnumModules(moduleNum);
641 if (pParserModule == NULL)
642 break;
643
644 /* see if this parser recognizes it */
645 if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
646 {
647 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
648 return result;
649 }
650
651 /* parser recognized the file, return the handle */
652 if (streamHandle)
653 {
654
655 /* save the parser pointer and file handle */
656 EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
657 *ppStream = &pEASData->streams[streamNum];
658 return EAS_SUCCESS;
659 }
660
661 /* rewind the file for the next parser */
662 if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, 0L)) != EAS_SUCCESS)
663 return result;
664 }
665
666 /* no parser was able to recognize the file, close it and return an error */
667 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
668 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
669 return EAS_ERROR_UNRECOGNIZED_FORMAT;
670 }
671
672 #ifdef MMAPI_SUPPORT
673 /*----------------------------------------------------------------------------
674 * EAS_MMAPIToneControl()
675 *----------------------------------------------------------------------------
676 * Purpose:
677 * Opens a ToneControl file for audio playback.
678 *
679 * Inputs:
680 * pEASData - pointer to overall EAS data structure
681 * pHandle - pointer to file handle
682 *
683 * Outputs:
684 *
685 *
686 * Side Effects:
687 *
688 *----------------------------------------------------------------------------
689 */
EAS_MMAPIToneControl(EAS_DATA_HANDLE pEASData,EAS_FILE_LOCATOR locator,EAS_HANDLE * ppStream)690 EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *ppStream)
691 {
692 EAS_RESULT result;
693 EAS_FILE_HANDLE fileHandle;
694 EAS_VOID_PTR streamHandle;
695 S_FILE_PARSER_INTERFACE *pParserModule;
696 EAS_INT streamNum;
697
698 /* check if the tone control parser is available */
699 *ppStream = NULL;
700 streamHandle = NULL;
701 pParserModule = EAS_CMEnumOptModules(EAS_MODULE_MMAPI_TONE_CONTROL);
702 if (pParserModule == NULL)
703 {
704 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_MMAPIToneControl: ToneControl parser not available\n"); */ }
705 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
706 }
707
708 /* open the file */
709 if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
710 return result;
711
712 /* allocate a stream */
713 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
714 return EAS_ERROR_MAX_STREAMS_OPEN;
715
716 /* see if ToneControl parser recognizes it */
717 if ((result = (*pParserModule->pfCheckFileType)(pEASData, fileHandle, &streamHandle, 0L)) != EAS_SUCCESS)
718 {
719 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "CheckFileType returned error %ld\n", result); */ }
720 return result;
721 }
722
723 /* parser accepted the file, return the handle */
724 if (streamHandle)
725 {
726
727 /* save the parser pointer and file handle */
728 EAS_InitStream(&pEASData->streams[streamNum], pParserModule, streamHandle);
729 *ppStream = &pEASData->streams[streamNum];
730 return EAS_SUCCESS;
731 }
732
733 /* parser did not recognize the file, close it and return an error */
734 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
735 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "No parser recognized the requested file\n"); */ }
736 return EAS_ERROR_UNRECOGNIZED_FORMAT;
737 }
738
739 /*----------------------------------------------------------------------------
740 * EAS_GetWaveFmtChunk
741 *----------------------------------------------------------------------------
742 * Helper function to retrieve WAVE file fmt chunk for MMAPI
743 *----------------------------------------------------------------------------
744 * pEASData - pointer to EAS persistent data object
745 * pStream - stream handle
746 * pFmtChunk - pointer to variable to receive current setting
747 *----------------------------------------------------------------------------
748 */
EAS_GetWaveFmtChunk(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_VOID_PTR * ppFmtChunk)749 EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_VOID_PTR *ppFmtChunk)
750 {
751 EAS_RESULT result;
752 EAS_I32 value;
753
754 if ((result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FORMAT, &value)) != EAS_SUCCESS)
755 return result;
756 *ppFmtChunk = (EAS_VOID_PTR) value;
757 return EAS_SUCCESS;
758 }
759 #endif
760
761 /*----------------------------------------------------------------------------
762 * EAS_GetFileType
763 *----------------------------------------------------------------------------
764 * Returns the file type (see eas_types.h for enumerations)
765 *----------------------------------------------------------------------------
766 * pEASData - pointer to EAS persistent data object
767 * pStream - stream handle
768 * pFileType - pointer to variable to receive file type
769 *----------------------------------------------------------------------------
770 */
EAS_GetFileType(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_I32 * pFileType)771 EAS_PUBLIC EAS_RESULT EAS_GetFileType (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_I32 *pFileType)
772 {
773 if (!EAS_StreamReady (pEASData, pStream))
774 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
775 return EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_FILE_TYPE, pFileType);
776 }
777
778 /*----------------------------------------------------------------------------
779 * EAS_Prepare()
780 *----------------------------------------------------------------------------
781 * Purpose:
782 * Prepares the synthesizer to play the file or stream. Parses the first
783 * frame of data from the file and arms the synthesizer.
784 *
785 * Inputs:
786 * pEASData - pointer to overall EAS data structure
787 * handle - file or stream handle
788 *
789 * Outputs:
790 *
791 *
792 * Side Effects:
793 *
794 *----------------------------------------------------------------------------
795 */
EAS_Prepare(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)796 EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
797 {
798 S_FILE_PARSER_INTERFACE *pParserModule;
799 EAS_STATE state;
800 EAS_RESULT result;
801
802 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
803 if (pParserModule == NULL)
804 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
805
806 /* check for valid state */
807 result = pParserModule->pfState(pEASData, pStream->handle, &state);
808 if (result == EAS_SUCCESS)
809 {
810 /* prepare the stream */
811 if (state == EAS_STATE_OPEN)
812 {
813 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
814 result = (*pParserModule->pfPrepare)(pEASData, pStream->handle);
815
816 /* set volume */
817 if (result == EAS_SUCCESS)
818 result = EAS_SetVolume(pEASData, pStream, pStream->volume);
819 }
820 else
821 result = EAS_ERROR_NOT_VALID_IN_THIS_STATE;
822
823 }
824
825 return result;
826 }
827
828 /*----------------------------------------------------------------------------
829 * EAS_Render()
830 *----------------------------------------------------------------------------
831 * Purpose:
832 * Parse the Midi data and render PCM audio data.
833 *
834 * Inputs:
835 * pEASData - buffer for internal EAS data
836 * pOut - output buffer pointer
837 * nNumRequested - requested num samples to generate
838 * pnNumGenerated - actual number of samples generated
839 *
840 * Outputs:
841 * EAS_SUCCESS if PCM data was successfully rendered
842 *
843 *----------------------------------------------------------------------------
844 */
EAS_Render(EAS_DATA_HANDLE pEASData,EAS_PCM * pOut,EAS_I32 numRequested,EAS_I32 * pNumGenerated)845 EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated)
846 {
847 S_FILE_PARSER_INTERFACE *pParserModule;
848 EAS_RESULT result;
849 EAS_I32 voicesRendered;
850 EAS_STATE parserState;
851 EAS_INT streamNum;
852
853 /* assume no samples generated and reset workload */
854 *pNumGenerated = 0;
855 VMInitWorkload(pEASData->pVoiceMgr);
856
857 /* no support for other buffer sizes yet */
858 if (numRequested != BUFFER_SIZE_IN_MONO_SAMPLES)
859 {
860 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "This library supports only %ld samples in buffer, host requested %ld samples\n",
861 (EAS_I32) BUFFER_SIZE_IN_MONO_SAMPLES, numRequested); */ }
862 return EAS_BUFFER_SIZE_MISMATCH;
863 }
864
865 #ifdef _METRICS_ENABLED
866 /* start performance counter */
867 if (pEASData->pMetricsData)
868 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
869 #endif
870
871 /* prep the frame buffer, do mix engine prep only if TRUE */
872 #ifdef _SPLIT_ARCHITECTURE
873 if (VMStartFrame(pEASData))
874 EAS_MixEnginePrep(pEASData, numRequested);
875 #else
876 /* prep the mix engine */
877 EAS_MixEnginePrep(pEASData, numRequested);
878 #endif
879
880 /* save the output buffer pointer */
881 pEASData->pOutputAudioBuffer = pOut;
882
883
884 #ifdef _METRICS_ENABLED
885 /* start performance counter */
886 if (pEASData->pMetricsData)
887 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
888 #endif
889
890 /* if we haven't finished parsing from last time, do it now */
891 /* need to parse another frame of events before we render again */
892 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
893 {
894 /* clear the locate flag */
895 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_LOCATE;
896
897 if (pEASData->streams[streamNum].pParserModule)
898 {
899
900 /* establish pointer to parser module */
901 pParserModule = pEASData->streams[streamNum].pParserModule;
902
903 /* handle pause */
904 if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PAUSE)
905 {
906 if (pParserModule->pfPause)
907 result = pParserModule->pfPause(pEASData, pEASData->streams[streamNum].handle);
908 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PAUSE;
909 }
910
911 /* get current state */
912 if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
913 return result;
914
915 /* handle resume */
916 if (parserState == EAS_STATE_PAUSED)
917 {
918 if (pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_RESUME)
919 {
920 if (pParserModule->pfResume)
921 result = pParserModule->pfResume(pEASData, pEASData->streams[streamNum].handle);
922 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_RESUME;
923 }
924 }
925
926 /* if necessary, parse stream */
927 if ((pEASData->streams[streamNum].streamFlags & STREAM_FLAGS_PARSED) == 0)
928 if ((result = EAS_ParseEvents(pEASData, &pEASData->streams[streamNum], pEASData->streams[streamNum].time + pEASData->streams[streamNum].frameLength, eParserModePlay)) != EAS_SUCCESS)
929 return result;
930
931 /* check for an early abort */
932 if ((pEASData->streams[streamNum].streamFlags) == 0)
933 {
934
935 #ifdef _METRICS_ENABLED
936 /* stop performance counter */
937 if (pEASData->pMetricsData)
938 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
939 #endif
940
941 return EAS_SUCCESS;
942 }
943
944 /* check for repeat */
945 if (pEASData->streams[streamNum].repeatCount)
946 {
947
948 /* check for stopped state */
949 if ((result = (*pParserModule->pfState)(pEASData, pEASData->streams[streamNum].handle, &parserState)) != EAS_SUCCESS)
950 return result;
951 if (parserState == EAS_STATE_STOPPED)
952 {
953
954 /* decrement repeat count, unless it is negative */
955 if (pEASData->streams[streamNum].repeatCount > 0)
956 pEASData->streams[streamNum].repeatCount--;
957
958 /* reset the parser */
959 if ((result = (*pParserModule->pfReset)(pEASData, pEASData->streams[streamNum].handle)) != EAS_SUCCESS)
960 return result;
961 pEASData->streams[streamNum].time = 0;
962 }
963 }
964 }
965 }
966
967 #ifdef _METRICS_ENABLED
968 /* stop performance counter */
969 if (pEASData->pMetricsData)
970 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_PARSE_TIME);
971 #endif
972
973 #ifdef _METRICS_ENABLED
974 /* start the render timer */
975 if (pEASData->pMetricsData)
976 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
977 #endif
978
979 /* render audio */
980 if ((result = VMRender(pEASData->pVoiceMgr, BUFFER_SIZE_IN_MONO_SAMPLES, pEASData->pMixBuffer, &voicesRendered)) != EAS_SUCCESS)
981 {
982 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "pfRender function returned error %ld\n", result); */ }
983 return result;
984 }
985
986 #ifdef _METRICS_ENABLED
987 /* stop the render timer */
988 if (pEASData->pMetricsData) {
989 (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_FRAME_COUNT, 1);
990 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_RENDER_TIME);
991 (*pEASData->pMetricsModule->pfIncrementCounter)(pEASData->pMetricsData, EAS_PM_TOTAL_VOICE_COUNT, (EAS_U32) voicesRendered);
992 (void)(*pEASData->pMetricsModule->pfRecordMaxValue)(pEASData->pMetricsData, EAS_PM_MAX_VOICES, (EAS_U32) voicesRendered);
993 }
994 #endif
995
996 //2 Do we really need frameParsed?
997 /* need to parse another frame of events before we render again */
998 for (streamNum = 0; streamNum < MAX_NUMBER_STREAMS; streamNum++)
999 if (pEASData->streams[streamNum].pParserModule != NULL)
1000 pEASData->streams[streamNum].streamFlags &= ~STREAM_FLAGS_PARSED;
1001
1002 #ifdef _METRICS_ENABLED
1003 /* start performance counter */
1004 if (pEASData->pMetricsData)
1005 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
1006 #endif
1007
1008 /* render PCM audio */
1009 if ((result = EAS_PERender(pEASData, numRequested)) != EAS_SUCCESS)
1010 {
1011 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_PERender returned error %ld\n", result); */ }
1012 return result;
1013 }
1014
1015 #ifdef _METRICS_ENABLED
1016 /* stop the stream timer */
1017 if (pEASData->pMetricsData)
1018 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_STREAM_TIME);
1019 #endif
1020
1021 #ifdef _METRICS_ENABLED
1022 /* start the post timer */
1023 if (pEASData->pMetricsData)
1024 (*pEASData->pMetricsModule->pfStartTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
1025 #endif
1026
1027 /* for split architecture, send DSP vectors. Do post only if return is TRUE */
1028 #ifdef _SPLIT_ARCHITECTURE
1029 if (VMEndFrame(pEASData))
1030 {
1031 /* now do post-processing */
1032 EAS_MixEnginePost(pEASData, numRequested);
1033 *pNumGenerated = numRequested;
1034 }
1035 #else
1036 /* now do post-processing */
1037 EAS_MixEnginePost(pEASData, numRequested);
1038 *pNumGenerated = numRequested;
1039 #endif
1040
1041 #ifdef _METRICS_ENABLED
1042 /* stop the post timer */
1043 if (pEASData->pMetricsData)
1044 (void)(*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_POST_TIME);
1045 #endif
1046
1047 /* advance render time */
1048 pEASData->renderTime += AUDIO_FRAME_LENGTH;
1049
1050 #if 0
1051 /* dump workload for debug */
1052 if (pEASData->pVoiceMgr->workload)
1053 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Workload = %d\n", pEASData->pVoiceMgr->workload); */ }
1054 #endif
1055
1056 #ifdef _METRICS_ENABLED
1057 /* stop performance counter */
1058 if (pEASData->pMetricsData)
1059 {
1060 PERF_TIMER temp;
1061 temp = (*pEASData->pMetricsModule->pfStopTimer)(pEASData->pMetricsData, EAS_PM_TOTAL_TIME);
1062
1063 /* if max render time, record the number of voices and time */
1064 if ((*pEASData->pMetricsModule->pfRecordMaxValue)
1065 (pEASData->pMetricsData, EAS_PM_MAX_CYCLES, (EAS_U32) temp))
1066 {
1067 (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_VOICES, (EAS_U32) voicesRendered);
1068 (*pEASData->pMetricsModule->pfRecordValue)(pEASData->pMetricsData, EAS_PM_MAX_CYCLES_TIME, (EAS_I32) (pEASData->renderTime >> 8));
1069 }
1070 }
1071 #endif
1072
1073 #ifdef JET_INTERFACE
1074 /* let JET to do its thing */
1075 if (pEASData->jetHandle != NULL)
1076 {
1077 result = JET_Process(pEASData);
1078 if (result != EAS_SUCCESS)
1079 return result;
1080 }
1081 #endif
1082
1083 return EAS_SUCCESS;
1084 }
1085
1086 /*----------------------------------------------------------------------------
1087 * EAS_SetRepeat()
1088 *----------------------------------------------------------------------------
1089 * Purpose:
1090 * Set the selected stream to repeat.
1091 *
1092 * Inputs:
1093 * pEASData - handle to data for this instance
1094 * handle - handle to stream
1095 * repeatCount - repeat count
1096 *
1097 * Outputs:
1098 *
1099 * Side Effects:
1100 *
1101 * Notes:
1102 * 0 = no repeat
1103 * 1 = repeat once, i.e. play through twice
1104 * -1 = repeat forever
1105 *----------------------------------------------------------------------------
1106 */
1107 /*lint -esym(715, pEASData) reserved for future use */
EAS_SetRepeat(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 repeatCount)1108 EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 repeatCount)
1109 {
1110 pStream->repeatCount = repeatCount;
1111 return EAS_SUCCESS;
1112 }
1113
1114 /*----------------------------------------------------------------------------
1115 * EAS_GetRepeat()
1116 *----------------------------------------------------------------------------
1117 * Purpose:
1118 * Gets the current repeat count for the selected stream.
1119 *
1120 * Inputs:
1121 * pEASData - handle to data for this instance
1122 * handle - handle to stream
1123 * pRrepeatCount - pointer to variable to hold repeat count
1124 *
1125 * Outputs:
1126 *
1127 * Side Effects:
1128 *
1129 * Notes:
1130 * 0 = no repeat
1131 * 1 = repeat once, i.e. play through twice
1132 * -1 = repeat forever
1133 *----------------------------------------------------------------------------
1134 */
1135 /*lint -esym(715, pEASData) reserved for future use */
EAS_GetRepeat(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * pRepeatCount)1136 EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pRepeatCount)
1137 {
1138 *pRepeatCount = pStream->repeatCount;
1139 return EAS_SUCCESS;
1140 }
1141
1142 /*----------------------------------------------------------------------------
1143 * EAS_SetPlaybackRate()
1144 *----------------------------------------------------------------------------
1145 * Purpose:
1146 * Sets the playback rate.
1147 *
1148 * Inputs:
1149 * pEASData - handle to data for this instance
1150 * handle - handle to stream
1151 * rate - rate (28-bit fractional amount)
1152 *
1153 * Outputs:
1154 *
1155 * Side Effects:
1156 *
1157 *----------------------------------------------------------------------------
1158 */
1159 /*lint -esym(715, pEASData) reserved for future use */
EAS_SetPlaybackRate(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_U32 rate)1160 EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U32 rate)
1161 {
1162
1163 /* check range */
1164 if ((rate < (1 << 27)) || (rate > (1 << 29)))
1165 return EAS_ERROR_INVALID_PARAMETER;
1166
1167 /* calculate new frame length
1168 *
1169 * NOTE: The maximum frame length we can accomodate based on a
1170 * maximum rate of 2.0 (2^28) is 2047 (2^13-1). To accomodate a
1171 * longer frame length or a higher maximum rate, the fixed point
1172 * divide below will need to be adjusted
1173 */
1174 pStream->frameLength = (AUDIO_FRAME_LENGTH * (rate >> 8)) >> 20;
1175
1176 /* notify stream of new playback rate */
1177 EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_PLAYBACK_RATE, (EAS_I32) rate);
1178 return EAS_SUCCESS;
1179 }
1180
1181 /*----------------------------------------------------------------------------
1182 * EAS_SetTransposition)
1183 *----------------------------------------------------------------------------
1184 * Purpose:
1185 * Sets the key tranposition for the synthesizer. Transposes all
1186 * melodic instruments by the specified amount. Range is limited
1187 * to +/-12 semitones.
1188 *
1189 * Inputs:
1190 * pEASData - handle to data for this instance
1191 * handle - handle to stream
1192 * transposition - +/-12 semitones
1193 *
1194 * Outputs:
1195 *
1196 * Side Effects:
1197 *
1198 *----------------------------------------------------------------------------
1199 */
EAS_SetTransposition(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 transposition)1200 EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 transposition)
1201 {
1202
1203 /* check range */
1204 if ((transposition < -12) || (transposition > 12))
1205 return EAS_ERROR_INVALID_PARAMETER;
1206
1207 if (!EAS_StreamReady(pEASData, pStream))
1208 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1209 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_TRANSPOSITION, transposition);
1210 }
1211
1212 /*----------------------------------------------------------------------------
1213 * EAS_ParseEvents()
1214 *----------------------------------------------------------------------------
1215 * Purpose:
1216 * Parse events in the current streams until the desired time is reached.
1217 *
1218 * Inputs:
1219 * pEASData - buffer for internal EAS data
1220 * endTime - stop parsing if this time is reached
1221 * parseMode - play, locate, or metadata
1222 *
1223 * Outputs:
1224 * EAS_SUCCESS if PCM data was successfully rendered
1225 *
1226 *----------------------------------------------------------------------------
1227 */
EAS_ParseEvents(S_EAS_DATA * pEASData,EAS_HANDLE pStream,EAS_U32 endTime,EAS_INT parseMode)1228 static EAS_RESULT EAS_ParseEvents (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_U32 endTime, EAS_INT parseMode)
1229 {
1230 S_FILE_PARSER_INTERFACE *pParserModule;
1231 EAS_RESULT result;
1232 EAS_I32 parserState;
1233 EAS_BOOL done;
1234 EAS_INT yieldCount = YIELD_EVENT_COUNT;
1235 EAS_U32 time = 0;
1236
1237 /* does this parser have a time function? */
1238 pParserModule = pStream->pParserModule;
1239 if (pParserModule->pfTime == NULL)
1240 {
1241 /* check state */
1242 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
1243 return result;
1244 /* if play state, advance time */
1245 if ((parserState >= EAS_STATE_READY) && (parserState <= EAS_STATE_PAUSING))
1246 pStream->time += pStream->frameLength;
1247 done = EAS_TRUE;
1248 }
1249
1250 /* assume we're not done, in case we abort out */
1251 else
1252 {
1253 pStream->streamFlags &= ~STREAM_FLAGS_PARSED;
1254 done = EAS_FALSE;
1255 }
1256
1257 while (!done)
1258 {
1259
1260 /* check for stopped state */
1261 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &parserState)) != EAS_SUCCESS)
1262 return result;
1263 if (parserState > EAS_STATE_PLAY)
1264 {
1265 /* save current time if we're not in play mode */
1266 if (parseMode != eParserModePlay)
1267 pStream->time = time << 8;
1268 done = EAS_TRUE;
1269 break;
1270 }
1271
1272 /* get the next event time */
1273 if (pParserModule->pfTime)
1274 {
1275 if ((result = (*pParserModule->pfTime)(pEASData, pStream->handle, &time)) != EAS_SUCCESS)
1276 return result;
1277
1278 /* if next event is within this frame, parse it */
1279 if (time < (endTime >> 8))
1280 {
1281
1282 /* parse the next event */
1283 if (pParserModule->pfEvent)
1284 if ((result = (*pParserModule->pfEvent)(pEASData, pStream->handle, parseMode)) != EAS_SUCCESS)
1285 return result;
1286 }
1287
1288 /* no more events in this frame, advance time */
1289 else
1290 {
1291 pStream->time = endTime;
1292 done = EAS_TRUE;
1293 }
1294 }
1295
1296 /* check for max workload exceeded */
1297 if (VMCheckWorkload(pEASData->pVoiceMgr))
1298 {
1299 /* stop even though we may not have parsed
1300 * all the events in this frame. The parser will try to
1301 * catch up on the next frame.
1302 */
1303 break;
1304 }
1305
1306 /* give host a chance for an early abort */
1307 if (--yieldCount == 0)
1308 {
1309 if (EAS_HWYield(pEASData->hwInstData))
1310 break;
1311 yieldCount = YIELD_EVENT_COUNT;
1312 }
1313 }
1314
1315 /* if no early abort, parsing is complete for this frame */
1316 if (done)
1317 pStream->streamFlags |= STREAM_FLAGS_PARSED;
1318
1319 return EAS_SUCCESS;
1320 }
1321
1322 /*----------------------------------------------------------------------------
1323 * EAS_ParseMetaData()
1324 *----------------------------------------------------------------------------
1325 * Purpose:
1326 *
1327 *
1328 * Inputs:
1329 * pEASData - pointer to overall EAS data structure
1330 * handle - file or stream handle
1331 * playLength - pointer to variable to store the play length (in msecs)
1332 *
1333 * Outputs:
1334 *
1335 *
1336 * Side Effects:
1337 * - resets the parser to the start of the file
1338 *----------------------------------------------------------------------------
1339 */
EAS_ParseMetaData(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * playLength)1340 EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *playLength)
1341 {
1342 S_FILE_PARSER_INTERFACE *pParserModule;
1343 EAS_RESULT result;
1344 EAS_STATE state;
1345
1346 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1347 if (pParserModule == NULL)
1348 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
1349
1350 /* check parser state */
1351 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
1352 return result;
1353 if (state >= EAS_STATE_OPEN)
1354 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1355
1356 /* if parser has metadata function, use that */
1357 if (pParserModule->pfGetMetaData != NULL)
1358 return pParserModule->pfGetMetaData(pEASData, pStream->handle, playLength);
1359
1360 /* reset the parser to the beginning */
1361 if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
1362 return result;
1363
1364 /* parse the file to end */
1365 pStream->time = 0;
1366 VMInitWorkload(pEASData->pVoiceMgr);
1367 if ((result = EAS_ParseEvents(pEASData, pStream, 0x7fffffff, eParserModeMetaData)) != EAS_SUCCESS)
1368 return result;
1369
1370 /* get the parser time */
1371 if ((result = EAS_GetLocation(pEASData, pStream, playLength)) != EAS_SUCCESS)
1372 return result;
1373
1374 /* reset the parser to the beginning */
1375 pStream->time = 0;
1376 return (*pParserModule->pfReset)(pEASData, pStream->handle);
1377 }
1378
1379 /*----------------------------------------------------------------------------
1380 * EAS_RegisterMetaDataCallback()
1381 *----------------------------------------------------------------------------
1382 * Purpose:
1383 * Registers a metadata callback function for parsed metadata.
1384 *
1385 * Inputs:
1386 * pEASData - pointer to overall EAS data structure
1387 * handle - file or stream handle
1388 * cbFunc - pointer to host callback function
1389 * metaDataBuffer - pointer to metadata buffer
1390 * metaDataBufSize - maximum size of the metadata buffer
1391 *
1392 * Outputs:
1393 *
1394 *
1395 * Side Effects:
1396 *
1397 *----------------------------------------------------------------------------
1398 */
EAS_RegisterMetaDataCallback(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_METADATA_CBFUNC cbFunc,char * metaDataBuffer,EAS_I32 metaDataBufSize,EAS_VOID_PTR pUserData)1399 EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
1400 EAS_DATA_HANDLE pEASData,
1401 EAS_HANDLE pStream,
1402 EAS_METADATA_CBFUNC cbFunc,
1403 char *metaDataBuffer,
1404 EAS_I32 metaDataBufSize,
1405 EAS_VOID_PTR pUserData)
1406 {
1407 S_METADATA_CB metadata;
1408
1409 if (!EAS_StreamReady(pEASData, pStream))
1410 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1411
1412 /* register callback function */
1413 metadata.callback = cbFunc;
1414 metadata.buffer = metaDataBuffer;
1415 metadata.bufferSize = metaDataBufSize;
1416 metadata.pUserData = pUserData;
1417 return EAS_SetStreamParameter(pEASData, pStream, PARSER_DATA_METADATA_CB, (EAS_I32) &metadata);
1418 }
1419
1420 /*----------------------------------------------------------------------------
1421 * EAS_GetNoteCount ()
1422 *----------------------------------------------------------------------------
1423 * Returns the total number of notes played in this stream
1424 *----------------------------------------------------------------------------
1425 */
EAS_GetNoteCount(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * pNoteCount)1426 EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount)
1427 {
1428 if (!EAS_StreamReady(pEASData, pStream))
1429 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1430 return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_NOTE_COUNT, pNoteCount);
1431 }
1432
1433 /*----------------------------------------------------------------------------
1434 * EAS_CloseFile()
1435 *----------------------------------------------------------------------------
1436 * Purpose:
1437 * Closes an audio file or stream. Playback should have either paused or
1438 * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
1439 *
1440 * Inputs:
1441 * pEASData - pointer to overall EAS data structure
1442 * handle - file or stream handle
1443 *
1444 * Outputs:
1445 *
1446 *
1447 * Side Effects:
1448 *
1449 *----------------------------------------------------------------------------
1450 */
EAS_CloseFile(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)1451 EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1452 {
1453 S_FILE_PARSER_INTERFACE *pParserModule;
1454 EAS_RESULT result;
1455
1456 /* call the close function */
1457 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1458 if (pParserModule == NULL)
1459 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
1460
1461 result = (*pParserModule->pfClose)(pEASData, pStream->handle);
1462
1463 /* clear the handle and parser interface pointer */
1464 pStream->handle = NULL;
1465 pStream->pParserModule = NULL;
1466 return result;
1467 }
1468
1469 /*----------------------------------------------------------------------------
1470 * EAS_OpenMIDIStream()
1471 *----------------------------------------------------------------------------
1472 * Purpose:
1473 * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
1474 *
1475 * Inputs:
1476 * pEASData - pointer to overall EAS data structure
1477 * pHandle - pointer to variable to hold file or stream handle
1478 *
1479 * Outputs:
1480 *
1481 *
1482 * Side Effects:
1483 *
1484 *----------------------------------------------------------------------------
1485 */
EAS_OpenMIDIStream(EAS_DATA_HANDLE pEASData,EAS_HANDLE * ppStream,EAS_HANDLE streamHandle)1486 EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *ppStream, EAS_HANDLE streamHandle)
1487 {
1488 EAS_RESULT result;
1489 S_INTERACTIVE_MIDI *pMIDIStream;
1490 EAS_INT streamNum;
1491
1492 /* initialize some pointers */
1493 *ppStream = NULL;
1494
1495 /* allocate a stream */
1496 if ((streamNum = EAS_AllocateStream(pEASData)) < 0)
1497 return EAS_ERROR_MAX_STREAMS_OPEN;
1498
1499 /* check Configuration Module for S_EAS_DATA allocation */
1500 if (pEASData->staticMemoryModel)
1501 pMIDIStream = EAS_CMEnumData(EAS_CM_MIDI_STREAM_DATA);
1502 else
1503 pMIDIStream = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_INTERACTIVE_MIDI));
1504
1505 /* allocate dynamic memory */
1506 if (!pMIDIStream)
1507 {
1508 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate MIDI stream data\n"); */ }
1509 return EAS_ERROR_MALLOC_FAILED;
1510 }
1511
1512 /* zero the memory to insure complete initialization */
1513 EAS_HWMemSet(pMIDIStream, 0, sizeof(S_INTERACTIVE_MIDI));
1514 EAS_InitStream(&pEASData->streams[streamNum], NULL, pMIDIStream);
1515
1516 /* instantiate a new synthesizer */
1517 if (streamHandle == NULL)
1518 {
1519 result = VMInitMIDI(pEASData, &pMIDIStream->pSynth);
1520 }
1521
1522 /* use an existing synthesizer */
1523 else
1524 {
1525 EAS_I32 value;
1526 result = EAS_GetStreamParameter(pEASData, streamHandle, PARSER_DATA_SYNTH_HANDLE, &value);
1527 pMIDIStream->pSynth = (S_SYNTH*) value;
1528 VMIncRefCount(pMIDIStream->pSynth);
1529 }
1530 if (result != EAS_SUCCESS)
1531 {
1532 EAS_CloseMIDIStream(pEASData, &pEASData->streams[streamNum]);
1533 return result;
1534 }
1535
1536 /* initialize the MIDI stream data */
1537 EAS_InitMIDIStream(&pMIDIStream->stream);
1538
1539 *ppStream = (EAS_HANDLE) &pEASData->streams[streamNum];
1540 return EAS_SUCCESS;
1541 }
1542
1543 /*----------------------------------------------------------------------------
1544 * EAS_WriteMIDIStream()
1545 *----------------------------------------------------------------------------
1546 * Purpose:
1547 * Send data to the MIDI stream device
1548 *
1549 * Inputs:
1550 * pEASData - pointer to overall EAS data structure
1551 * handle - stream handle
1552 * pBuffer - pointer to buffer
1553 * count - number of bytes to write
1554 *
1555 * Outputs:
1556 *
1557 *
1558 * Side Effects:
1559 *
1560 *----------------------------------------------------------------------------
1561 */
EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_U8 * pBuffer,EAS_I32 count)1562 EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 *pBuffer, EAS_I32 count)
1563 {
1564 S_INTERACTIVE_MIDI *pMIDIStream;
1565 EAS_RESULT result;
1566
1567 pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
1568
1569 /* send the entire buffer */
1570 while (count--)
1571 {
1572 if ((result = EAS_ParseMIDIStream(pEASData, pMIDIStream->pSynth, &pMIDIStream->stream, *pBuffer++, eParserModePlay)) != EAS_SUCCESS)
1573 return result;
1574 }
1575 return EAS_SUCCESS;
1576 }
1577
1578 /*----------------------------------------------------------------------------
1579 * EAS_CloseMIDIStream()
1580 *----------------------------------------------------------------------------
1581 * Purpose:
1582 * Closes a raw MIDI stream
1583 *
1584 * Inputs:
1585 * pEASData - pointer to overall EAS data structure
1586 * handle - stream handle
1587 *
1588 * Outputs:
1589 *
1590 *
1591 * Side Effects:
1592 *
1593 *----------------------------------------------------------------------------
1594 */
EAS_CloseMIDIStream(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)1595 EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1596 {
1597 S_INTERACTIVE_MIDI *pMIDIStream;
1598
1599 pMIDIStream = (S_INTERACTIVE_MIDI*) pStream->handle;
1600
1601 /* close synth */
1602 if (pMIDIStream->pSynth != NULL)
1603 {
1604 VMMIDIShutdown(pEASData, pMIDIStream->pSynth);
1605 pMIDIStream->pSynth = NULL;
1606 }
1607
1608 /* release allocated memory */
1609 if (!pEASData->staticMemoryModel)
1610 EAS_HWFree(((S_EAS_DATA*) pEASData)->hwInstData, pMIDIStream);
1611
1612 pStream->handle = NULL;
1613 return EAS_SUCCESS;
1614 }
1615
1616 /*----------------------------------------------------------------------------
1617 * EAS_State()
1618 *----------------------------------------------------------------------------
1619 * Purpose:
1620 * Returns the state of an audio file or stream.
1621 *
1622 * Inputs:
1623 * pEASData - pointer to overall EAS data structure
1624 * handle - file or stream handle
1625 *
1626 * Outputs:
1627 *
1628 *
1629 * Side Effects:
1630 *
1631 *----------------------------------------------------------------------------
1632 */
EAS_State(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_STATE * pState)1633 EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_STATE *pState)
1634 {
1635 S_FILE_PARSER_INTERFACE *pParserModule;
1636 EAS_RESULT result;
1637
1638 /* call the parser to return state */
1639 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1640 if (pParserModule == NULL)
1641 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
1642
1643 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, pState)) != EAS_SUCCESS)
1644 return result;
1645
1646 /* if repeat count is set for this parser, mask the stopped state from the application */
1647 if (pStream->repeatCount && (*pState == EAS_STATE_STOPPED))
1648 *pState = EAS_STATE_PLAY;
1649
1650 /* if we're not ready or playing, we don't need to hide state from host */
1651 if (*pState > EAS_STATE_PLAY)
1652 return EAS_SUCCESS;
1653
1654 /* if stream is about to be paused, report it as paused */
1655 if (pStream->streamFlags & STREAM_FLAGS_PAUSE)
1656 {
1657 if (pStream->streamFlags & STREAM_FLAGS_LOCATE)
1658 *pState = EAS_STATE_PAUSED;
1659 else
1660 *pState = EAS_STATE_PAUSING;
1661 }
1662
1663 /* if stream is about to resume, report it as playing */
1664 if (pStream->streamFlags & STREAM_FLAGS_RESUME)
1665 *pState = EAS_STATE_PLAY;
1666
1667 return EAS_SUCCESS;
1668 }
1669
1670 /*----------------------------------------------------------------------------
1671 * EAS_SetPolyphony()
1672 *----------------------------------------------------------------------------
1673 * Purpose:
1674 * Set the polyphony of the stream. A value of 0 allows the stream
1675 * to use all voices (set by EAS_SetSynthPolyphony).
1676 *
1677 * Inputs:
1678 * pEASData - pointer to overall EAS data structure
1679 * streamHandle - handle returned by EAS_OpenFile
1680 * polyphonyCount - the desired polyphony count
1681 *
1682 * Outputs:
1683 *
1684 * Side Effects:
1685 *
1686 *----------------------------------------------------------------------------
1687 */
EAS_SetPolyphony(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 polyphonyCount)1688 EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 polyphonyCount)
1689 {
1690 if (!EAS_StreamReady(pEASData, pStream))
1691 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1692 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, polyphonyCount);
1693 }
1694
1695 /*----------------------------------------------------------------------------
1696 * EAS_GetPolyphony()
1697 *----------------------------------------------------------------------------
1698 * Purpose:
1699 * Returns the current polyphony setting of the stream
1700 *
1701 * Inputs:
1702 * pEASData - pointer to overall EAS data structure
1703 * streamHandle - handle returned by EAS_OpenFile
1704 * pPolyphonyCount - pointer to variable to receive polyphony count
1705 *
1706 * Outputs:
1707 *
1708 * Side Effects:
1709 *
1710 *----------------------------------------------------------------------------
1711 */
EAS_GetPolyphony(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * pPolyphonyCount)1712 EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPolyphonyCount)
1713 {
1714 if (!EAS_StreamReady(pEASData, pStream))
1715 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1716 return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_POLYPHONY, pPolyphonyCount);
1717 }
1718
1719 /*----------------------------------------------------------------------------
1720 * EAS_SetSynthPolyphony()
1721 *----------------------------------------------------------------------------
1722 * Purpose:
1723 * Set the polyphony of the synth . Value must be >= 1 and <= the
1724 * maximum number of voices. This function will pin the polyphony
1725 * at those limits
1726 *
1727 * Inputs:
1728 * pEASData - pointer to overall EAS data structure
1729 * synthNum - synthesizer number (0 = onboard, 1 = DSP)
1730 * polyphonyCount - the desired polyphony count
1731 *
1732 * Outputs:
1733 *
1734 * Side Effects:
1735 *
1736 *----------------------------------------------------------------------------
1737 */
EAS_SetSynthPolyphony(EAS_DATA_HANDLE pEASData,EAS_I32 synthNum,EAS_I32 polyphonyCount)1738 EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount)
1739 {
1740 return VMSetSynthPolyphony(pEASData->pVoiceMgr, synthNum, polyphonyCount);
1741 }
1742
1743 /*----------------------------------------------------------------------------
1744 * EAS_GetSynthPolyphony()
1745 *----------------------------------------------------------------------------
1746 * Purpose:
1747 * Returns the current polyphony setting of the synth
1748 *
1749 * Inputs:
1750 * pEASData - pointer to overall EAS data structure
1751 * synthNum - synthesizer number (0 = onboard, 1 = DSP)
1752 * pPolyphonyCount - pointer to variable to receive polyphony count
1753 *
1754 * Outputs:
1755 *
1756 * Side Effects:
1757 *
1758 *----------------------------------------------------------------------------
1759 */
EAS_GetSynthPolyphony(EAS_DATA_HANDLE pEASData,EAS_I32 synthNum,EAS_I32 * pPolyphonyCount)1760 EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount)
1761 {
1762 return VMGetSynthPolyphony(pEASData->pVoiceMgr, synthNum, pPolyphonyCount);
1763 }
1764
1765 /*----------------------------------------------------------------------------
1766 * EAS_SetPriority()
1767 *----------------------------------------------------------------------------
1768 * Purpose:
1769 * Set the priority of the stream. Determines which stream's voices
1770 * are stolen when there are insufficient voices for all notes.
1771 * Value must be in the range of 1-15, lower values are higher
1772 * priority.
1773 *
1774 * Inputs:
1775 * pEASData - pointer to overall EAS data structure
1776 * streamHandle - handle returned by EAS_OpenFile
1777 * polyphonyCount - the desired polyphony count
1778 *
1779 * Outputs:
1780 *
1781 * Side Effects:
1782 *
1783 *----------------------------------------------------------------------------
1784 */
EAS_SetPriority(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 priority)1785 EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 priority)
1786 {
1787 if (!EAS_StreamReady(pEASData, pStream))
1788 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1789 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, priority);
1790 }
1791
1792 /*----------------------------------------------------------------------------
1793 * EAS_GetPriority()
1794 *----------------------------------------------------------------------------
1795 * Purpose:
1796 * Returns the current priority setting of the stream
1797 *
1798 * Inputs:
1799 * pEASData - pointer to overall EAS data structure
1800 * streamHandle - handle returned by EAS_OpenFile
1801 * pPriority - pointer to variable to receive priority
1802 *
1803 * Outputs:
1804 *
1805 * Side Effects:
1806 *
1807 *----------------------------------------------------------------------------
1808 */
EAS_GetPriority(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * pPriority)1809 EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pPriority)
1810 {
1811 if (!EAS_StreamReady(pEASData, pStream))
1812 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1813 return EAS_IntGetStrmParam(pEASData, pStream, PARSER_DATA_PRIORITY, pPriority);
1814 }
1815
1816 /*----------------------------------------------------------------------------
1817 * EAS_SetVolume()
1818 *----------------------------------------------------------------------------
1819 * Purpose:
1820 * Set the master gain for the mix engine in 1dB increments
1821 *
1822 * Inputs:
1823 * pEASData - pointer to overall EAS data structure
1824 * volume - the desired master gain (100 is max)
1825 * handle - file or stream handle
1826 *
1827 * Outputs:
1828 *
1829 *
1830 * Side Effects:
1831 * overrides any previously set master volume from sysex
1832 *
1833 *----------------------------------------------------------------------------
1834 */
EAS_SetVolume(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 volume)1835 EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 volume)
1836 {
1837 EAS_I16 gain;
1838
1839 /* check range */
1840 if ((volume < 0) || (volume > EAS_MAX_VOLUME))
1841 return EAS_ERROR_PARAMETER_RANGE;
1842
1843 /* stream volume */
1844 if (pStream != NULL)
1845 {
1846 EAS_I32 gainOffset;
1847 EAS_RESULT result;
1848
1849 if (!EAS_StreamReady(pEASData, pStream))
1850 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1851
1852 /* get gain offset */
1853 pStream->volume = (EAS_U8) volume;
1854 result = EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_GAIN_OFFSET, &gainOffset);
1855 if (result == EAS_SUCCESS)
1856 volume += gainOffset;
1857
1858 /* set stream volume */
1859 gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
1860
1861 /* convert to linear scalar */
1862 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_VOLUME, gain);
1863 }
1864
1865 /* master volume */
1866 pEASData->masterVolume = (EAS_U8) volume;
1867 #if (NUM_OUTPUT_CHANNELS == 1)
1868 /* leave 3dB headroom for mono output */
1869 volume -= 3;
1870 #endif
1871
1872 gain = EAS_VolumeToGain(volume - STREAM_VOLUME_HEADROOM);
1873 pEASData->masterGain = gain;
1874 return EAS_SUCCESS;
1875 }
1876
1877 /*----------------------------------------------------------------------------
1878 * EAS_GetVolume()
1879 *----------------------------------------------------------------------------
1880 * Purpose:
1881 * Returns the master volume for the synthesizer. The default volume setting is
1882 * 50. The volume range is 0 to 100;
1883 *
1884 * Inputs:
1885 * pEASData - pointer to overall EAS data structure
1886 * volume - the desired master volume
1887 * handle - file or stream handle
1888 *
1889 * Outputs:
1890 *
1891 *
1892 * Side Effects:
1893 * overrides any previously set master volume from sysex
1894 *
1895 *----------------------------------------------------------------------------
1896 */
EAS_GetVolume(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)1897 EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
1898 {
1899 if (pStream == NULL)
1900 return pEASData->masterVolume;
1901
1902 if (!EAS_StreamReady(pEASData, pStream))
1903 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1904 return pStream->volume;
1905 }
1906
1907 /*----------------------------------------------------------------------------
1908 * EAS_SetMaxLoad()
1909 *----------------------------------------------------------------------------
1910 * Purpose:
1911 * Sets the maximum workload the parsers will do in a single call to
1912 * EAS_Render. The units are currently arbitrary, but should correlate
1913 * well to the actual CPU cycles consumed. The primary effect is to
1914 * reduce the occasional peaks in CPU cycles consumed when parsing
1915 * dense parts of a MIDI score.
1916 *
1917 * Inputs:
1918 * pEASData - handle to data for this instance
1919 * maxLoad - the desired maximum workload
1920 *
1921 * Outputs:
1922 *
1923 * Side Effects:
1924 *
1925 *----------------------------------------------------------------------------
1926 */
EAS_SetMaxLoad(EAS_DATA_HANDLE pEASData,EAS_I32 maxLoad)1927 EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad)
1928 {
1929 VMSetWorkload(pEASData->pVoiceMgr, maxLoad);
1930 return EAS_SUCCESS;
1931 }
1932
1933 /*----------------------------------------------------------------------------
1934 * EAS_SetMaxPCMStreams()
1935 *----------------------------------------------------------------------------
1936 * Sets the maximum number of PCM streams allowed in parsers that
1937 * use PCM streaming.
1938 *
1939 * Inputs:
1940 * pEASData - pointer to overall EAS data structure
1941 * streamHandle - handle returned by EAS_OpenFile
1942 * maxNumStreams - maximum number of PCM streams
1943 *----------------------------------------------------------------------------
1944 */
EAS_SetMaxPCMStreams(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 maxNumStreams)1945 EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams)
1946 {
1947 if (!EAS_StreamReady(pEASData, pStream))
1948 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1949 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_MAX_PCM_STREAMS, maxNumStreams);
1950 }
1951
1952 /*----------------------------------------------------------------------------
1953 * EAS_Locate()
1954 *----------------------------------------------------------------------------
1955 * Purpose:
1956 * Locate into the file associated with the handle.
1957 *
1958 * Inputs:
1959 * pEASData - pointer to overall EAS data structure
1960 * handle - file handle
1961 * milliseconds - playback offset from start of file in milliseconds
1962 *
1963 * Outputs:
1964 *
1965 *
1966 * Side Effects:
1967 * the actual offset will be quantized to the closest update period, typically
1968 * a resolution of 5.9ms. Notes that are started prior to this time will not
1969 * sound. Any notes currently playing will be shut off.
1970 *
1971 *----------------------------------------------------------------------------
1972 */
EAS_Locate(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 milliseconds,EAS_BOOL offset)1973 EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 milliseconds, EAS_BOOL offset)
1974 {
1975 S_FILE_PARSER_INTERFACE *pParserModule;
1976 EAS_RESULT result;
1977 EAS_U32 requestedTime;
1978 EAS_STATE state;
1979
1980 /* get pointer to parser function table */
1981 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
1982 if (pParserModule == NULL)
1983 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
1984
1985 if ((result = (*pParserModule->pfState)(pEASData, pStream->handle, &state)) != EAS_SUCCESS)
1986 return result;
1987 if (state >= EAS_STATE_OPEN)
1988 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
1989
1990 /* handle offset and limit to start of file */
1991 /*lint -e{704} use shift for performance*/
1992 if (offset)
1993 milliseconds += (EAS_I32) pStream->time >> 8;
1994 if (milliseconds < 0)
1995 milliseconds = 0;
1996
1997 /* check to see if the request is different from the current time */
1998 requestedTime = (EAS_U32) milliseconds;
1999 if (requestedTime == (pStream->time >> 8))
2000 return EAS_SUCCESS;
2001
2002 /* set the locate flag */
2003 pStream->streamFlags |= STREAM_FLAGS_LOCATE;
2004
2005 /* use the parser locate function, if available */
2006 if (pParserModule->pfLocate != NULL)
2007 {
2008 EAS_BOOL parserLocate = EAS_FALSE;
2009 result = pParserModule->pfLocate(pEASData, pStream->handle, (EAS_I32) requestedTime, &parserLocate);
2010 if (!parserLocate)
2011 {
2012 if (result == EAS_SUCCESS)
2013 pStream->time = requestedTime << 8;
2014 return result;
2015 }
2016 }
2017
2018 /* if we were paused and not going to resume, set pause request flag */
2019 if (((state == EAS_STATE_PAUSING) || (state == EAS_STATE_PAUSED)) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
2020 pStream->streamFlags |= STREAM_FLAGS_PAUSE;
2021
2022 /* reset the synth and parser */
2023 if ((result = (*pParserModule->pfReset)(pEASData, pStream->handle)) != EAS_SUCCESS)
2024 return result;
2025 pStream->time = 0;
2026
2027 /* locating forward, clear parsed flag and parse data until we get to the requested location */
2028 if ((result = EAS_ParseEvents(pEASData, pStream, requestedTime << 8, eParserModeLocate)) != EAS_SUCCESS)
2029 return result;
2030
2031 return EAS_SUCCESS;
2032 }
2033
2034 /*----------------------------------------------------------------------------
2035 * EAS_GetLocation()
2036 *----------------------------------------------------------------------------
2037 * Purpose:
2038 * Returns the current playback offset
2039 *
2040 * Inputs:
2041 * pEASData - pointer to overall EAS data structure
2042 * handle - file handle
2043 *
2044 * Outputs:
2045 * The offset in milliseconds from the start of the current sequence, quantized
2046 * to the nearest update period. Actual resolution is typically 5.9 ms.
2047 *
2048 * Side Effects:
2049 *
2050 *----------------------------------------------------------------------------
2051 */
2052 /*lint -esym(715, pEASData) reserved for future use */
EAS_GetLocation(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 * pTime)2053 EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pTime)
2054 {
2055 if (!EAS_StreamReady(pEASData, pStream))
2056 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2057
2058 *pTime = pStream->time >> 8;
2059 return EAS_SUCCESS;
2060 }
2061
2062 /*----------------------------------------------------------------------------
2063 * EAS_GetRenderTime()
2064 *----------------------------------------------------------------------------
2065 * Purpose:
2066 * Returns the current playback offset
2067 *
2068 * Inputs:
2069 * pEASData - pointer to overall EAS data structure
2070 *
2071 * Outputs:
2072 * Gets the render time clock in msecs.
2073 *
2074 * Side Effects:
2075 *
2076 *----------------------------------------------------------------------------
2077 */
EAS_GetRenderTime(EAS_DATA_HANDLE pEASData,EAS_I32 * pTime)2078 EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime)
2079 {
2080 *pTime = pEASData->renderTime >> 8;
2081 return EAS_SUCCESS;
2082 }
2083
2084 /*----------------------------------------------------------------------------
2085 * EAS_Pause()
2086 *----------------------------------------------------------------------------
2087 * Purpose:
2088 * Pauses the playback of the data associated with this handle. The audio
2089 * is gracefully ramped down to prevent clicks and pops. It may take several
2090 * buffers of audio before the audio is muted.
2091 *
2092 * Inputs:
2093 * psEASData - pointer to overall EAS data structure
2094 * handle - file or stream handle
2095 *
2096 * Outputs:
2097 *
2098 *
2099 * Side Effects:
2100 *
2101 *
2102 *----------------------------------------------------------------------------
2103 */
EAS_Pause(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)2104 EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
2105 {
2106 S_FILE_PARSER_INTERFACE *pParserModule;
2107 EAS_STATE state;
2108 EAS_RESULT result;
2109
2110 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
2111 if (pParserModule == NULL)
2112 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
2113
2114 /* check for valid state */
2115 result = pParserModule->pfState(pEASData, pStream->handle, &state);
2116 if (result == EAS_SUCCESS)
2117 {
2118 if ((state != EAS_STATE_PLAY) && (state != EAS_STATE_READY) && ((pStream->streamFlags & STREAM_FLAGS_RESUME) == 0))
2119 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2120
2121 /* make sure parser implements pause */
2122 if (pParserModule->pfPause == NULL)
2123 result = EAS_ERROR_NOT_IMPLEMENTED;
2124
2125 /* clear resume flag */
2126 pStream->streamFlags &= ~STREAM_FLAGS_RESUME;
2127
2128 /* set pause flag */
2129 pStream->streamFlags |= STREAM_FLAGS_PAUSE;
2130
2131 #if 0
2132 /* pause the stream */
2133 if (pParserModule->pfPause)
2134 result = pParserModule->pfPause(pEASData, pStream->handle);
2135 else
2136 result = EAS_ERROR_NOT_IMPLEMENTED;
2137 #endif
2138 }
2139
2140 return result;
2141 }
2142
2143 /*----------------------------------------------------------------------------
2144 * EAS_Resume()
2145 *----------------------------------------------------------------------------
2146 * Purpose:
2147 * Resumes the playback of the data associated with this handle. The audio
2148 * is gracefully ramped up to prevent clicks and pops.
2149 *
2150 * Inputs:
2151 * psEASData - pointer to overall EAS data structure
2152 * handle - file or stream handle
2153 *
2154 * Outputs:
2155 *
2156 *
2157 * Side Effects:
2158 *
2159 *
2160 *----------------------------------------------------------------------------
2161 */
EAS_Resume(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream)2162 EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream)
2163 {
2164 S_FILE_PARSER_INTERFACE *pParserModule;
2165 EAS_STATE state;
2166 EAS_RESULT result;
2167
2168 pParserModule = (S_FILE_PARSER_INTERFACE*) pStream->pParserModule;
2169 if (pParserModule == NULL)
2170 return EAS_ERROR_FEATURE_NOT_AVAILABLE;
2171
2172 /* check for valid state */
2173 result = pParserModule->pfState(pEASData, pStream->handle, &state);
2174 if (result == EAS_SUCCESS)
2175 {
2176 if ((state != EAS_STATE_PAUSED) && (state != EAS_STATE_PAUSING) && ((pStream->streamFlags & STREAM_FLAGS_PAUSE) == 0))
2177 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2178
2179 /* make sure parser implements this function */
2180 if (pParserModule->pfResume == NULL)
2181 result = EAS_ERROR_NOT_IMPLEMENTED;
2182
2183 /* clear pause flag */
2184 pStream->streamFlags &= ~STREAM_FLAGS_PAUSE;
2185
2186 /* set resume flag */
2187 pStream->streamFlags |= STREAM_FLAGS_RESUME;
2188
2189 #if 0
2190 /* resume the stream */
2191 if (pParserModule->pfResume)
2192 result = pParserModule->pfResume(pEASData, pStream->handle);
2193 else
2194 result = EAS_ERROR_NOT_IMPLEMENTED;
2195 #endif
2196 }
2197
2198 return result;
2199 }
2200
2201 /*----------------------------------------------------------------------------
2202 * EAS_GetParameter()
2203 *----------------------------------------------------------------------------
2204 * Purpose:
2205 * Set the parameter of a module. See E_MODULES for a list of modules
2206 * and the header files of the modules for a list of parameters.
2207 *
2208 * Inputs:
2209 * psEASData - pointer to overall EAS data structure
2210 * handle - file or stream handle
2211 * module - enumerated module number
2212 * param - enumerated parameter number
2213 * pValue - pointer to variable to receive parameter value
2214 *
2215 * Outputs:
2216 *
2217 *
2218 * Side Effects:
2219 *
2220 *
2221 *----------------------------------------------------------------------------
2222 */
EAS_GetParameter(EAS_DATA_HANDLE pEASData,EAS_I32 module,EAS_I32 param,EAS_I32 * pValue)2223 EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue)
2224 {
2225
2226 if (module >= NUM_EFFECTS_MODULES)
2227 return EAS_ERROR_INVALID_MODULE;
2228
2229 if (pEASData->effectsModules[module].effectData == NULL)
2230 return EAS_ERROR_INVALID_MODULE;
2231
2232 return (*pEASData->effectsModules[module].effect->pFGetParam)
2233 (pEASData->effectsModules[module].effectData, param, pValue);
2234 }
2235
2236 /*----------------------------------------------------------------------------
2237 * EAS_SetParameter()
2238 *----------------------------------------------------------------------------
2239 * Purpose:
2240 * Set the parameter of a module. See E_MODULES for a list of modules
2241 * and the header files of the modules for a list of parameters.
2242 *
2243 * Inputs:
2244 * psEASData - pointer to overall EAS data structure
2245 * handle - file or stream handle
2246 * module - enumerated module number
2247 * param - enumerated parameter number
2248 * value - new parameter value
2249 *
2250 * Outputs:
2251 *
2252 *
2253 * Side Effects:
2254 *
2255 *
2256 *----------------------------------------------------------------------------
2257 */
EAS_SetParameter(EAS_DATA_HANDLE pEASData,EAS_I32 module,EAS_I32 param,EAS_I32 value)2258 EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value)
2259 {
2260
2261 if (module >= NUM_EFFECTS_MODULES)
2262 return EAS_ERROR_INVALID_MODULE;
2263
2264 if (pEASData->effectsModules[module].effectData == NULL)
2265 return EAS_ERROR_INVALID_MODULE;
2266
2267 return (*pEASData->effectsModules[module].effect->pFSetParam)
2268 (pEASData->effectsModules[module].effectData, param, value);
2269 }
2270
2271 #ifdef _METRICS_ENABLED
2272 /*----------------------------------------------------------------------------
2273 * EAS_MetricsReport()
2274 *----------------------------------------------------------------------------
2275 * Purpose:
2276 * Displays the current metrics through the metrics interface.
2277 *
2278 * Inputs:
2279 * p - instance data handle
2280 *
2281 * Outputs:
2282 *
2283 *
2284 * Side Effects:
2285 *
2286 *----------------------------------------------------------------------------
2287 */
EAS_MetricsReport(EAS_DATA_HANDLE pEASData)2288 EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData)
2289 {
2290 if (!pEASData->pMetricsModule)
2291 return EAS_ERROR_INVALID_MODULE;
2292
2293 return (*pEASData->pMetricsModule->pfReport)(pEASData->pMetricsData);
2294 }
2295
2296 /*----------------------------------------------------------------------------
2297 * EAS_MetricsReset()
2298 *----------------------------------------------------------------------------
2299 * Purpose:
2300 * Resets the metrics.
2301 *
2302 * Inputs:
2303 * p - instance data handle
2304 *
2305 * Outputs:
2306 *
2307 *
2308 * Side Effects:
2309 *
2310 *----------------------------------------------------------------------------
2311 */
EAS_MetricsReset(EAS_DATA_HANDLE pEASData)2312 EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData)
2313 {
2314
2315 if (!pEASData->pMetricsModule)
2316 return EAS_ERROR_INVALID_MODULE;
2317
2318 return (*pEASData->pMetricsModule->pfReset)(pEASData->pMetricsData);
2319 }
2320 #endif
2321
2322 /*----------------------------------------------------------------------------
2323 * EAS_SetSoundLibrary()
2324 *----------------------------------------------------------------------------
2325 * Purpose:
2326 * Sets the location of the sound library.
2327 *
2328 * Inputs:
2329 * pEASData - instance data handle
2330 * pSoundLib - pointer to sound library
2331 *
2332 * Outputs:
2333 *
2334 *
2335 * Side Effects:
2336 *
2337 *----------------------------------------------------------------------------
2338 */
EAS_SetSoundLibrary(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_SNDLIB_HANDLE pSndLib)2339 EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_SNDLIB_HANDLE pSndLib)
2340 {
2341 if (pStream)
2342 {
2343 if (!EAS_StreamReady(pEASData, pStream))
2344 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2345 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_EAS_LIBRARY, (EAS_I32) pSndLib);
2346 }
2347
2348 return VMSetGlobalEASLib(pEASData->pVoiceMgr, pSndLib);
2349 }
2350
2351 /*----------------------------------------------------------------------------
2352 * EAS_SetHeaderSearchFlag()
2353 *----------------------------------------------------------------------------
2354 * By default, when EAS_OpenFile is called, the parsers check the
2355 * first few bytes of the file looking for a specific header. Some
2356 * mobile devices may add a header to the start of a file, which
2357 * will prevent the parser from recognizing the file. If the
2358 * searchFlag is set to EAS_TRUE, the parser will search the entire
2359 * file looking for the header. This may enable EAS to recognize
2360 * some files that it would ordinarily reject. The negative is that
2361 * it make take slightly longer to process the EAS_OpenFile request.
2362 *
2363 * Inputs:
2364 * pEASData - instance data handle
2365 * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
2366 *----------------------------------------------------------------------------
2367 */
EAS_SetHeaderSearchFlag(EAS_DATA_HANDLE pEASData,EAS_BOOL searchFlag)2368 EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag)
2369 {
2370 pEASData->searchHeaderFlag = (EAS_BOOL8) searchFlag;
2371 return EAS_SUCCESS;
2372 }
2373
2374 /*----------------------------------------------------------------------------
2375 * EAS_SetPlayMode()
2376 *----------------------------------------------------------------------------
2377 * Some file formats support special play modes, such as iMode partial
2378 * play mode. This call can be used to change the play mode. The
2379 * default play mode (usually straight playback) is always zero.
2380 *
2381 * Inputs:
2382 * pEASData - instance data handle
2383 * handle - file or stream handle
2384 * playMode - play mode (see file parser for specifics)
2385 *----------------------------------------------------------------------------
2386 */
EAS_SetPlayMode(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_I32 playMode)2387 EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode)
2388 {
2389 return EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_PLAY_MODE, playMode);
2390 }
2391
2392 #ifdef DLS_SYNTHESIZER
2393 /*----------------------------------------------------------------------------
2394 * EAS_LoadDLSCollection()
2395 *----------------------------------------------------------------------------
2396 * Purpose:
2397 * Sets the location of the sound library.
2398 *
2399 * Inputs:
2400 * pEASData - instance data handle
2401 * pSoundLib - pointer to sound library
2402 *
2403 * Outputs:
2404 *
2405 *
2406 * Side Effects:
2407 *
2408 *----------------------------------------------------------------------------
2409 */
EAS_LoadDLSCollection(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_FILE_LOCATOR locator)2410 EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_FILE_LOCATOR locator)
2411 {
2412 EAS_FILE_HANDLE fileHandle;
2413 EAS_RESULT result;
2414 EAS_DLSLIB_HANDLE pDLS;
2415
2416 if (pStream != NULL)
2417 {
2418 if (!EAS_StreamReady(pEASData, pStream))
2419 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2420 }
2421
2422 /* open the file */
2423 if ((result = EAS_HWOpenFile(pEASData->hwInstData, locator, &fileHandle, EAS_FILE_READ)) != EAS_SUCCESS)
2424 return result;
2425
2426 /* parse the file */
2427 result = DLSParser(pEASData->hwInstData, fileHandle, 0, &pDLS);
2428 EAS_HWCloseFile(pEASData->hwInstData, fileHandle);
2429
2430 if (result == EAS_SUCCESS)
2431 {
2432
2433 /* if a stream pStream is specified, point it to the DLS collection */
2434 if (pStream)
2435 result = EAS_IntSetStrmParam(pEASData, pStream, PARSER_DATA_DLS_COLLECTION, (EAS_I32) pDLS);
2436
2437 /* global DLS load */
2438 else
2439 result = VMSetGlobalDLSLib(pEASData, pDLS);
2440 }
2441
2442 return result;
2443 }
2444 #endif
2445
2446 #ifdef EXTERNAL_AUDIO
2447 /*----------------------------------------------------------------------------
2448 * EAS_RegExtAudioCallback()
2449 *----------------------------------------------------------------------------
2450 * Purpose:
2451 * Registers callback functions for audio events.
2452 *
2453 * Inputs:
2454 * pEASData - pointer to overall EAS data structure
2455 * handle - file or stream handle
2456 * cbProgChgFunc - pointer to host callback function for program change
2457 * cbEventFunc - pointer to host callback functio for note events
2458 *
2459 * Outputs:
2460 *
2461 *
2462 * Side Effects:
2463 *
2464 *----------------------------------------------------------------------------
2465 */
EAS_RegExtAudioCallback(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_VOID_PTR pInstData,EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,EAS_EXT_EVENT_FUNC cbEventFunc)2466 EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
2467 EAS_HANDLE pStream,
2468 EAS_VOID_PTR pInstData,
2469 EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
2470 EAS_EXT_EVENT_FUNC cbEventFunc)
2471 {
2472 S_SYNTH *pSynth;
2473
2474 if (!EAS_StreamReady(pEASData, pStream))
2475 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2476
2477 if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
2478 return EAS_ERROR_INVALID_PARAMETER;
2479
2480 if (pSynth == NULL)
2481 return EAS_ERROR_INVALID_PARAMETER;
2482
2483 VMRegExtAudioCallback(pSynth, pInstData, cbProgChgFunc, cbEventFunc);
2484 return EAS_SUCCESS;
2485 }
2486
2487 /*----------------------------------------------------------------------------
2488 * EAS_GetMIDIControllers()
2489 *----------------------------------------------------------------------------
2490 * Purpose:
2491 * Returns the current state of MIDI controllers on the requested channel.
2492 *
2493 * Inputs:
2494 * pEASData - pointer to overall EAS data structure
2495 * handle - file or stream handle
2496 * pControl - pointer to structure to receive data
2497 *
2498 * Outputs:
2499 *
2500 *
2501 * Side Effects:
2502 *
2503 *----------------------------------------------------------------------------
2504 */
EAS_GetMIDIControllers(EAS_DATA_HANDLE pEASData,EAS_HANDLE pStream,EAS_U8 channel,S_MIDI_CONTROLLERS * pControl)2505 EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl)
2506 {
2507 S_SYNTH *pSynth;
2508
2509 if (!EAS_StreamReady(pEASData, pStream))
2510 return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
2511
2512 if (EAS_GetStreamParameter(pEASData, pStream, PARSER_DATA_SYNTH_HANDLE, (EAS_I32*) &pSynth) != EAS_SUCCESS)
2513 return EAS_ERROR_INVALID_PARAMETER;
2514
2515 if (pSynth == NULL)
2516 return EAS_ERROR_INVALID_PARAMETER;
2517
2518 VMGetMIDIControllers(pSynth, channel, pControl);
2519 return EAS_SUCCESS;
2520 }
2521 #endif
2522
2523 #ifdef _SPLIT_ARCHITECTURE
2524 /*----------------------------------------------------------------------------
2525 * EAS_SetFrameBuffer()
2526 *----------------------------------------------------------------------------
2527 * Purpose:
2528 * Sets the frame buffer pointer passed to the IPC communications functions
2529 *
2530 * Inputs:
2531 * pEASData - instance data handle
2532 * locator - file locator
2533 *
2534 * Outputs:
2535 *
2536 *
2537 * Side Effects:
2538 * May overlay instruments in the GM sound set
2539 *
2540 *----------------------------------------------------------------------------
2541 */
EAS_SetFrameBuffer(EAS_DATA_HANDLE pEASData,EAS_FRAME_BUFFER_HANDLE pFrameBuffer)2542 EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
2543 {
2544 if (pEASData->pVoiceMgr)
2545 pEASData->pVoiceMgr->pFrameBuffer = pFrameBuffer;
2546 return EAS_SUCCESS;
2547 }
2548 #endif
2549
2550 /*----------------------------------------------------------------------------
2551 * EAS_SearchFile
2552 *----------------------------------------------------------------------------
2553 * Search file for specific sequence starting at current file
2554 * position. Returns offset to start of sequence.
2555 *
2556 * Inputs:
2557 * pEASData - pointer to EAS persistent data object
2558 * fileHandle - file handle
2559 * searchString - pointer to search sequence
2560 * len - length of search sequence
2561 * pOffset - pointer to variable to store offset to sequence
2562 *
2563 * Returns EAS_EOF if end-of-file is reached
2564 *----------------------------------------------------------------------------
2565 */
EAS_SearchFile(S_EAS_DATA * pEASData,EAS_FILE_HANDLE fileHandle,const EAS_U8 * searchString,EAS_I32 len,EAS_I32 * pOffset)2566 EAS_RESULT EAS_SearchFile (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset)
2567 {
2568 EAS_RESULT result;
2569 EAS_INT index;
2570 EAS_U8 c;
2571
2572 *pOffset = -1;
2573 index = 0;
2574 for (;;)
2575 {
2576 result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &c);
2577 if (result != EAS_SUCCESS)
2578 return result;
2579 if (c == searchString[index])
2580 {
2581 index++;
2582 if (index == 4)
2583 {
2584 result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, pOffset);
2585 if (result != EAS_SUCCESS)
2586 return result;
2587 *pOffset -= len;
2588 break;
2589 }
2590 }
2591 else
2592 index = 0;
2593 }
2594 return EAS_SUCCESS;
2595 }
2596
2597
2598