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