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