Home | History | Annotate | Download | only in host_src
      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  */
     81 typedef 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 
     89 typedef 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 */
    101 EAS_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 */
    120 EAS_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 */
    136 void *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 */
    150 void 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 */
    163 void *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 */
    176 void *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 */
    189 EAS_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 */
    202 EAS_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 */
    275 EAS_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 */
    309 EAS_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 */
    337 EAS_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 */
    366 EAS_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 */
    399 EAS_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 */
    419 EAS_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 */
    444 EAS_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 */
    470 EAS_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 */
    489 EAS_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 */
    532 EAS_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 */
    596 EAS_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 */
    611 EAS_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 */
    626 EAS_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 */
    655 EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
    656 {
    657     /* put your code here */
    658     return EAS_FALSE;
    659 }
    660 
    661