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