1/*---------------------------------------------------------------------------- 2 * 3 * File: 4 * eas_hostmm.c 5 * 6 * Contents and purpose: 7 * This file contains the host wrapper functions for stdio, stdlib, etc. 8 * This is a sample version that maps the requested files to an 9 * allocated memory block and uses in-memory pointers to replace 10 * file system calls. The file locator (EAS_FILE_LOCATOR) handle passed 11 * HWOpenFile is the same one that is passed to EAS_OpenFile. If your 12 * system stores data in fixed locations (such as flash) instead of 13 * using a file system, you can use the locator handle to point to 14 * your memory. You will need a way of knowing the length of the 15 * data stored at that location in order to respond correctly in the 16 * HW_FileLength function. 17 * 18 * Modify this file to suit the needs of your particular system. 19 * 20 * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within 21 * a MIDI type 1 file that can be played. 22 * 23 * EAS_HW_FILE is a structure to support the file I/O functions. It 24 * comprises the base memory pointer, the file read pointer, and 25 * the dup flag, which when sets, indicates that the file handle has 26 * been duplicated. If your system uses in-memory resources, you 27 * can eliminate the duplicate handle logic, and simply copy the 28 * base memory pointer and file read pointer to the duplicate handle. 29 * 30 * Copyright 2005 Sonic Network Inc. 31 32 * Licensed under the Apache License, Version 2.0 (the "License"); 33 * you may not use this file except in compliance with the License. 34 * You may obtain a copy of the License at 35 * 36 * http://www.apache.org/licenses/LICENSE-2.0 37 * 38 * Unless required by applicable law or agreed to in writing, software 39 * distributed under the License is distributed on an "AS IS" BASIS, 40 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 41 * See the License for the specific language governing permissions and 42 * limitations under the License. 43 * 44 *---------------------------------------------------------------------------- 45 * Revision Control: 46 * $Revision: 795 $ 47 * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $ 48 *---------------------------------------------------------------------------- 49*/ 50 51#ifdef _lint 52#include "lint_stdlib.h" 53#else 54#include <stdio.h> 55#include <stdlib.h> 56#include <string.h> 57#endif 58 59#include "eas_host.h" 60 61/* Only for debugging LED, vibrate, and backlight functions */ 62#include "eas_report.h" 63 64/* this module requires dynamic memory support */ 65#ifdef _STATIC_MEMORY 66#error "eas_hostmm.c requires the dynamic memory model!\n" 67#endif 68 69#ifndef EAS_MAX_FILE_HANDLES 70#define EAS_MAX_FILE_HANDLES 32 71#endif 72 73/* 74 * this structure and the related function are here 75 * to support the ability to create duplicate handles 76 * and buffering it in memory. If your system uses 77 * in-memory resources, you can eliminate the calls 78 * to malloc and free, the dup flag, and simply track 79 * the file size and read position. 80 */ 81typedef struct eas_hw_file_tag 82{ 83 EAS_I32 fileSize; 84 EAS_I32 filePos; 85 EAS_BOOL dup; 86 EAS_U8 *buffer; 87} EAS_HW_FILE; 88 89typedef struct eas_hw_inst_data_tag 90{ 91 EAS_HW_FILE files[EAS_MAX_FILE_HANDLES]; 92} EAS_HW_INST_DATA; 93 94/*---------------------------------------------------------------------------- 95 * EAS_HWInit 96 * 97 * Initialize host wrapper interface 98 * 99 *---------------------------------------------------------------------------- 100*/ 101EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData) 102{ 103 104 /* need to track file opens for duplicate handles */ 105 *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA)); 106 if (!(*pHWInstData)) 107 return EAS_ERROR_MALLOC_FAILED; 108 109 EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA)); 110 return EAS_SUCCESS; 111} 112 113/*---------------------------------------------------------------------------- 114 * EAS_HWShutdown 115 * 116 * Shut down host wrapper interface 117 * 118 *---------------------------------------------------------------------------- 119*/ 120EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData) 121{ 122 123 free(hwInstData); 124 return EAS_SUCCESS; 125} 126 127/*---------------------------------------------------------------------------- 128 * 129 * EAS_HWMalloc 130 * 131 * Allocates dynamic memory 132 * 133 *---------------------------------------------------------------------------- 134*/ 135/*lint -esym(715, hwInstData) hwInstData available for customer use */ 136void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size) 137{ 138 return malloc((size_t) size); 139} 140 141/*---------------------------------------------------------------------------- 142 * 143 * EAS_HWFree 144 * 145 * Frees dynamic memory 146 * 147 *---------------------------------------------------------------------------- 148*/ 149/*lint -esym(715, hwInstData) hwInstData available for customer use */ 150void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p) 151{ 152 free(p); 153} 154 155/*---------------------------------------------------------------------------- 156 * 157 * EAS_HWMemCpy 158 * 159 * Copy memory wrapper 160 * 161 *---------------------------------------------------------------------------- 162*/ 163void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount) 164{ 165 return memcpy(dest, src, (size_t) amount); 166} 167 168/*---------------------------------------------------------------------------- 169 * 170 * EAS_HWMemSet 171 * 172 * Set memory wrapper 173 * 174 *---------------------------------------------------------------------------- 175*/ 176void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount) 177{ 178 return memset(dest, val, (size_t) amount); 179} 180 181/*---------------------------------------------------------------------------- 182 * 183 * EAS_HWMemCmp 184 * 185 * Compare memory wrapper 186 * 187 *---------------------------------------------------------------------------- 188*/ 189EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount) 190{ 191 return (EAS_I32) memcmp(s1, s2, (size_t) amount); 192} 193 194/*---------------------------------------------------------------------------- 195 * 196 * EAS_HWOpenFile 197 * 198 * Open a file for read or write 199 * 200 *---------------------------------------------------------------------------- 201*/ 202EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode) 203{ 204 EAS_HW_FILE *file; 205 FILE *ioFile; 206 int i, temp; 207 208 /* set return value to NULL */ 209 *pFile = NULL; 210 211 /* only support read mode at this time */ 212 if (mode != EAS_FILE_READ) 213 return EAS_ERROR_INVALID_FILE_MODE; 214 215 /* find an empty entry in the file table */ 216 file = hwInstData->files; 217 for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) 218 { 219 /* is this slot being used? */ 220 if (file->buffer == NULL) 221 { 222 /* open the file */ 223 if ((ioFile = fopen(locator,"rb")) == NULL) 224 return EAS_ERROR_FILE_OPEN_FAILED; 225 226 /* determine the file size */ 227 if (fseek(ioFile, 0L, SEEK_END) != 0) 228 return EAS_ERROR_FILE_LENGTH; 229 if ((file->fileSize = ftell(ioFile)) == -1L) 230 return EAS_ERROR_FILE_LENGTH; 231 if (fseek(ioFile, 0L, SEEK_SET) != 0) 232 return EAS_ERROR_FILE_LENGTH; 233 234 /* allocate a buffer */ 235 file->buffer = EAS_HWMalloc(hwInstData, file->fileSize); 236 if (file->buffer == NULL) 237 { 238 fclose(ioFile); 239 return EAS_ERROR_MALLOC_FAILED; 240 } 241 242 /* read the file into memory */ 243 temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile); 244 245 /* close the file - don't need it any more */ 246 fclose(ioFile); 247 248 /* check for error reading file */ 249 if (temp != 1) 250 return EAS_ERROR_FILE_READ_FAILED; 251 252 /* initialize some values */ 253 file->filePos = 0; 254 file->dup = EAS_FALSE; 255 256 *pFile = file; 257 return EAS_SUCCESS; 258 } 259 file++; 260 } 261 262 /* too many open files */ 263 return EAS_ERROR_MAX_FILES_OPEN; 264} 265 266/*---------------------------------------------------------------------------- 267 * 268 * EAS_HWReadFile 269 * 270 * Read data from a file 271 * 272 *---------------------------------------------------------------------------- 273*/ 274/*lint -esym(715, hwInstData) hwInstData available for customer use */ 275EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead) 276{ 277 EAS_I32 count; 278 279 /* make sure we have a valid handle */ 280 if (file->buffer == NULL) 281 return EAS_ERROR_INVALID_HANDLE; 282 283 /* calculate the bytes to read */ 284 count = file->fileSize - file->filePos; 285 if (n < count) 286 count = n; 287 288 /* copy the data to the requested location, and advance the pointer */ 289 if (count) 290 EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count); 291 file->filePos += count; 292 *pBytesRead = count; 293 294 /* were n bytes read? */ 295 if (count!= n) 296 return EAS_EOF; 297 return EAS_SUCCESS; 298} 299 300/*---------------------------------------------------------------------------- 301 * 302 * EAS_HWGetByte 303 * 304 * Read a byte from a file 305 * 306 *---------------------------------------------------------------------------- 307*/ 308/*lint -esym(715, hwInstData) hwInstData available for customer use */ 309EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p) 310{ 311 312 /* make sure we have a valid handle */ 313 if (file->buffer == NULL) 314 return EAS_ERROR_INVALID_HANDLE; 315 316 /* check for end of file */ 317 if (file->filePos >= file->fileSize) 318 { 319 *((EAS_U8*) p) = 0; 320 return EAS_EOF; 321 } 322 323 /* get a character from the buffer */ 324 *((EAS_U8*) p) = file->buffer[file->filePos++]; 325 return EAS_SUCCESS; 326} 327 328/*---------------------------------------------------------------------------- 329 * 330 * EAS_HWGetWord 331 * 332 * Returns the current location in the file 333 * 334 *---------------------------------------------------------------------------- 335*/ 336/*lint -esym(715, hwInstData) hwInstData available for customer use */ 337EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst) 338{ 339 EAS_RESULT result; 340 EAS_U8 c1, c2; 341 342 /* read 2 bytes from the file */ 343 if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS) 344 return result; 345 if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS) 346 return result; 347 348 /* order them as requested */ 349 if (msbFirst) 350 *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2; 351 else 352 *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1; 353 354 return EAS_SUCCESS; 355} 356 357/*---------------------------------------------------------------------------- 358 * 359 * EAS_HWGetDWord 360 * 361 * Returns the current location in the file 362 * 363 *---------------------------------------------------------------------------- 364*/ 365/*lint -esym(715, hwInstData) hwInstData available for customer use */ 366EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst) 367{ 368 EAS_RESULT result; 369 EAS_U8 c1, c2,c3,c4; 370 371 /* read 4 bytes from the file */ 372 if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS) 373 return result; 374 if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS) 375 return result; 376 if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS) 377 return result; 378 if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS) 379 return result; 380 381 /* order them as requested */ 382 if (msbFirst) 383 *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4; 384 else 385 *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1; 386 387 return EAS_SUCCESS; 388} 389 390/*---------------------------------------------------------------------------- 391 * 392 * EAS_HWFilePos 393 * 394 * Returns the current location in the file 395 * 396 *---------------------------------------------------------------------------- 397*/ 398/*lint -esym(715, hwInstData) hwInstData available for customer use */ 399EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition) 400{ 401 402 /* make sure we have a valid handle */ 403 if (file->buffer == NULL) 404 return EAS_ERROR_INVALID_HANDLE; 405 406 *pPosition = file->filePos; 407 return EAS_SUCCESS; 408} /* end EAS_HWFilePos */ 409 410/*---------------------------------------------------------------------------- 411 * 412 * EAS_HWFileSeek 413 * 414 * Seek to a specific location in the file 415 * 416 *---------------------------------------------------------------------------- 417*/ 418/*lint -esym(715, hwInstData) hwInstData available for customer use */ 419EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position) 420{ 421 422 /* make sure we have a valid handle */ 423 if (file->buffer == NULL) 424 return EAS_ERROR_INVALID_HANDLE; 425 426 /* validate new position */ 427 if ((position < 0) || (position > file->fileSize)) 428 return EAS_ERROR_FILE_SEEK; 429 430 /* save new position */ 431 file->filePos = position; 432 return EAS_SUCCESS; 433} 434 435/*---------------------------------------------------------------------------- 436 * 437 * EAS_HWFileSeekOfs 438 * 439 * Seek forward or back relative to the current position 440 * 441 *---------------------------------------------------------------------------- 442*/ 443/*lint -esym(715, hwInstData) hwInstData available for customer use */ 444EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position) 445{ 446 447 /* make sure we have a valid handle */ 448 if (file->buffer == NULL) 449 return EAS_ERROR_INVALID_HANDLE; 450 451 /* determine the file position */ 452 position += file->filePos; 453 if ((position < 0) || (position > file->fileSize)) 454 return EAS_ERROR_FILE_SEEK; 455 456 /* save new position */ 457 file->filePos = position; 458 return EAS_SUCCESS; 459} 460 461/*---------------------------------------------------------------------------- 462 * 463 * EAS_HWFileLength 464 * 465 * Return the file length 466 * 467 *---------------------------------------------------------------------------- 468*/ 469/*lint -esym(715, hwInstData) hwInstData available for customer use */ 470EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength) 471{ 472 473 /* make sure we have a valid handle */ 474 if (file->buffer == NULL) 475 return EAS_ERROR_INVALID_HANDLE; 476 477 *pLength = file->fileSize; 478 return EAS_SUCCESS; 479} 480 481/*---------------------------------------------------------------------------- 482 * 483 * EAS_HWDupHandle 484 * 485 * Duplicate a file handle 486 * 487 *---------------------------------------------------------------------------- 488*/ 489EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile) 490{ 491 EAS_HW_FILE *dupFile; 492 int i; 493 494 /* make sure we have a valid handle */ 495 if (file->buffer == NULL) 496 return EAS_ERROR_INVALID_HANDLE; 497 498 /* find an empty entry in the file table */ 499 dupFile = hwInstData->files; 500 for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) 501 { 502 /* is this slot being used? */ 503 if (dupFile->buffer == NULL) 504 { 505 506 /* copy info from the handle to be duplicated */ 507 dupFile->filePos = file->filePos; 508 dupFile->fileSize = file->fileSize; 509 dupFile->buffer = file->buffer; 510 511 /* set the duplicate handle flag */ 512 dupFile->dup = file->dup = EAS_TRUE; 513 514 *pDupFile = dupFile; 515 return EAS_SUCCESS; 516 } 517 dupFile++; 518 } 519 520 /* too many open files */ 521 return EAS_ERROR_MAX_FILES_OPEN; 522} 523 524/*---------------------------------------------------------------------------- 525 * 526 * EAS_HWClose 527 * 528 * Wrapper for fclose function 529 * 530 *---------------------------------------------------------------------------- 531*/ 532EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1) 533{ 534 EAS_HW_FILE *file2,*dupFile; 535 int i; 536 537 538 /* make sure we have a valid handle */ 539 if (file1->buffer == NULL) 540 return EAS_ERROR_INVALID_HANDLE; 541 542 /* check for duplicate handle */ 543 if (file1->dup) 544 { 545 dupFile = NULL; 546 file2 = hwInstData->files; 547 for (i = 0; i < EAS_MAX_FILE_HANDLES; i++) 548 { 549 /* check for duplicate */ 550 if ((file1 != file2) && (file2->buffer == file1->buffer)) 551 { 552 /* is there more than one duplicate? */ 553 if (dupFile != NULL) 554 { 555 /* clear this entry and return */ 556 file1->buffer = NULL; 557 return EAS_SUCCESS; 558 } 559 560 /* this is the first duplicate found */ 561 else 562 dupFile = file2; 563 } 564 file2++; 565 } 566 567 /* there is only one duplicate, clear the dup flag */ 568 if (dupFile) 569 dupFile->dup = EAS_FALSE; 570 else 571 /* if we get here, there's a serious problem */ 572 return EAS_ERROR_HANDLE_INTEGRITY; 573 574 /* clear this entry and return */ 575 file1->buffer = NULL; 576 return EAS_SUCCESS; 577 } 578 579 /* no duplicates -free the buffer */ 580 EAS_HWFree(hwInstData, file1->buffer); 581 582 /* clear this entry and return */ 583 file1->buffer = NULL; 584 return EAS_SUCCESS; 585} 586 587/*---------------------------------------------------------------------------- 588 * 589 * EAS_HWVibrate 590 * 591 * Turn on/off vibrate function 592 * 593 *---------------------------------------------------------------------------- 594*/ 595/*lint -esym(715, hwInstData) hwInstData available for customer use */ 596EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) 597{ 598 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state); 599 return EAS_SUCCESS; 600} /* end EAS_HWVibrate */ 601 602/*---------------------------------------------------------------------------- 603 * 604 * EAS_HWLED 605 * 606 * Turn on/off LED 607 * 608 *---------------------------------------------------------------------------- 609*/ 610/*lint -esym(715, hwInstData) hwInstData available for customer use */ 611EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) 612{ 613 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state); 614 return EAS_SUCCESS; 615} 616 617/*---------------------------------------------------------------------------- 618 * 619 * EAS_HWBackLight 620 * 621 * Turn on/off backlight 622 * 623 *---------------------------------------------------------------------------- 624*/ 625/*lint -esym(715, hwInstData) hwInstData available for customer use */ 626EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state) 627{ 628 EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state); 629 return EAS_SUCCESS; 630} 631 632/*---------------------------------------------------------------------------- 633 * 634 * EAS_HWYield 635 * 636 * This function is called periodically by the EAS library to give the 637 * host an opportunity to allow other tasks to run. There are two ways to 638 * use this call: 639 * 640 * If you have a multi-tasking OS, you can call the yield function in the 641 * OS to allow other tasks to run. In this case, return EAS_FALSE to tell 642 * the EAS library to continue processing when control returns from this 643 * function. 644 * 645 * If tasks run in a single thread by sequential function calls (sometimes 646 * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to 647 * return to the caller. Be sure to check the number of bytes rendered 648 * before passing the audio buffer to the codec - it may not be filled. 649 * The next call to EAS_Render will continue processing until the buffer 650 * has been filled. 651 * 652 *---------------------------------------------------------------------------- 653*/ 654/*lint -esym(715, hwInstData) hwInstData available for customer use */ 655EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData) 656{ 657 /* put your code here */ 658 return EAS_FALSE; 659} 660 661