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