Android多媒体开发(4)————移植Libmad到android平台

Android多媒体开发(4)————移植Libmad到android平台

http://blog.csdn.net/conowen/article/details/7727145
 
分类: Android多媒体&流媒体开发

/********************************************************************************************
 * author:conowen@大钟                                                                                                                          
 * E-mail:conowen@hotmail.com                                                                                                             
 * http://blog.csdn.net/conowen                                                                                                              
 * 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。     

 ********************************************************************************************/


       众所周知,Android的audiotrack只能播放原始的音频,也就是PCM数据,若是播放mp3编码格式的音频的话,就是出现沙沙的噪音。所以,可以使用第三方库Libmad来对mp3文件解码称为PCM数据,再送给audiotrack播放即可。


1、Libmad简介

          Libmad是一个开源的高精度 MPEG 音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3)。LIBMAD 提供 24-bit 的 PCM 输出,完全是定点计算,非常适合没有浮点支持的平台上使用。使用 libmad 提供的一系列 API,就可以非常简单地实现 MP3 数据解码工作。在 libmad 的源代码文件目录下的 mad.h 文件中,可以看到绝大部分该库的数据结构和 API 等。


2、实现过程

2.1、下载Android平台下的Libmad工程

http://gitorious.org/rowboat/external-libmad

或者直接执行

  1. mkdir libmad  
  2. cd libmad  
  3. git clone git://gitorious.org/rowboat/external-libmad.git  
mkdir libmad
cd libmad
git clone git://gitorious.org/rowboat/external-libmad.git


下载的project可以直接用NDK编译通过的,但是要使用还是要写jni层供java层调用,关于NDK开发,可以参看我之前的博文。

但是Android.mk要改成如下形式。

  1. #ifeq ($(strip $(BUILD_WITH_GST)),true)  
  2.   
  3. LOCAL_PATH:= $(call my-dir)  
  4.   
  5. include $(CLEAR_VARS)  
  6.   
  7. LOCAL_SRC_FILES:= \  
  8.     version.c \  
  9.     fixed.c \  
  10.     bit.c \  
  11.     timer.c \  
  12.     stream.c \  
  13.     frame.c  \  
  14.     synth.c \  
  15.     decoder.c \  
  16.     layer12.c \  
  17.     layer3.c \  
  18.     huffman.c  
  19.   
  20. LOCAL_ARM_MODE := arm  
  21.   
  22. LOCAL_MODULE:= libmad  
  23.   
  24. LOCAL_C_INCLUDES := \  
  25.     $(LOCAL_PATH)/android   
  26.   
  27. LOCAL_CFLAGS := -DHAVE_CONFIG_H -DFPM_ARM -ffast-math -O3  
  28.   
  29. include $(BUILD_SHARED_LIBRARY)  
  30.   
  31. #endif  
#ifeq ($(strip $(BUILD_WITH_GST)),true)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	version.c \
	fixed.c \
	bit.c \
	timer.c \
	stream.c \
	frame.c  \
	synth.c \
	decoder.c \
	layer12.c \
	layer3.c \
	huffman.c

LOCAL_ARM_MODE := arm

LOCAL_MODULE:= libmad

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/android 

LOCAL_CFLAGS := -DHAVE_CONFIG_H -DFPM_ARM -ffast-math -O3

include $(BUILD_SHARED_LIBRARY)

#endif

2.2、C代码编写API

需要注意一点的是,得到音频的Samplerate(采样率)要先进行一次readSamples操作才能发采样率读出。具体看代码即可。


  1. #define TAG "NativeMP3Decoder"   
  2.   
  3.   
  4. #include "FileSystem.h"   
  5.   
  6. #include "Mad.h"   
  7. #include "NativeMP3Decoder.h"   
  8. #include <stdio.h>   
  9. #include <string.h>   
  10. #include <stdlib.h>   
  11. #include <android/log.h>   
  12.   
  13.   
  14.   
  15.   
  16. #define SHRT_MAX (32767)   
  17. #define INPUT_BUFFER_SIZE   (8192/4)   
  18. #define OUTPUT_BUFFER_SIZE  8192 /* Must be an integer multiple of 4. */   
  19.   
  20. //int g_size;   
  21.   
  22. extern int file_open(const char *filename, int flags);  
  23. extern int file_read(T_pFILE fd, unsigned char *buf, int size);  
  24. extern int file_write(T_pFILE fd, unsigned char *buf, int size);  
  25. extern int64_t file_seek(T_pFILE fd, int64_t pos, int whence);  
  26. extern int file_close(T_pFILE fd);  
  27.   
  28. /** 
  29.  * Struct holding the pointer to a wave file. 
  30.  */  
  31. typedef struct  
  32. {  
  33.     int size;  
  34.     int64_t fileStartPos;  
  35.     T_pFILE file;  
  36.     struct mad_stream stream;  
  37.     struct mad_frame frame;  
  38.     struct mad_synth synth;  
  39.     mad_timer_t timer;  
  40.     int leftSamples;  
  41.     int offset;  
  42.     unsigned char inputBuffer[INPUT_BUFFER_SIZE];  
  43. } MP3FileHandle;  
  44.   
  45.   
  46. /** static WaveFileHandle array **/  
  47. static inline int readNextFrame( MP3FileHandle* mp3 );  
  48.   
  49. static MP3FileHandle* Handle;  
  50. unsigned int g_Samplerate;  
  51.   
  52. /** 
  53.  * Seeks a free handle in the handles array and returns its index or -1 if no handle could be found 
  54.  */  
  55.   
  56. static inline void closeHandle()  
  57. {  
  58.     file_close( Handle->file);  
  59.     mad_synth_finish(&Handle->synth);  
  60.     mad_frame_finish(&Handle->frame);  
  61.     mad_stream_finish(&Handle->stream);  
  62.     free(Handle);  
  63.     Handle = NULL;  
  64. }  
  65.   
  66. static inline signed short fixedToShort(mad_fixed_t Fixed)  
  67. {  
  68.     if(Fixed>=MAD_F_ONE)  
  69.         return(SHRT_MAX);  
  70.     if(Fixed<=-MAD_F_ONE)  
  71.         return(-SHRT_MAX);  
  72.   
  73.     Fixed=Fixed>>(MAD_F_FRACBITS-15);  
  74.     return((signed short)Fixed);  
  75. }  
  76.   
  77.   
  78. int  NativeMP3Decoder_init(char * filepath,unsigned long start/*,unsigned long size*/)  
  79. {  
  80.   
  81.     __android_log_print(ANDROID_LOG_INFO, TAG, "start = %d*******\n",start);  
  82.   
  83.    // __android_log_print(ANDROID_LOG_INFO, TAG, "size = %d*******\n",size);   
  84.   
  85.   
  86.     //g_size=size;   
  87.   
  88.   
  89.     T_pFILE fileHandle = file_open( filepath, _FMODE_READ);  
  90.     if( fileHandle == 0 )  
  91.         return -1;  
  92.   
  93.     MP3FileHandle* mp3Handle = (MP3FileHandle*)malloc(sizeof(MP3FileHandle));  
  94.     memset(mp3Handle, 0, sizeof(MP3FileHandle));  
  95.     mp3Handle->file = fileHandle;  
  96.   
  97.   
  98.    // mp3Handle->size = size;   
  99.     mp3Handle->fileStartPos= start;  
  100.   
  101.     file_seek( mp3Handle->file, start, SEEK_SET);  
  102.   
  103.     mad_stream_init(&mp3Handle->stream);  
  104.     mad_frame_init(&mp3Handle->frame);  
  105.     mad_synth_init(&mp3Handle->synth);  
  106.     mad_timer_reset(&mp3Handle->timer);  
  107.   
  108.     Handle = mp3Handle;  
  109.   
  110.   
  111.     readNextFrame( Handle );  
  112.   
  113.     g_Samplerate = Handle->frame.header.samplerate;  
  114.     return 1;  
  115. }  
  116.   
  117. static inline int readNextFrame( MP3FileHandle* mp3 )  
  118. {  
  119.     do  
  120.     {  
  121.         if( mp3->stream.buffer == 0 || mp3->stream.error == MAD_ERROR_BUFLEN )  
  122.         {  
  123.             int inputBufferSize = 0;  
  124.   
  125.             if( mp3->stream.next_frame != 0 )  
  126.             {  
  127.   
  128.                 int leftOver = mp3->stream.bufend - mp3->stream.next_frame;  
  129.                 int i;  
  130.                 for(  i= 0; i < leftOver; i++ )  
  131.                     mp3->inputBuffer[i] = mp3->stream.next_frame[i];  
  132.                 int readBytes = file_read( mp3->file, mp3->inputBuffer + leftOver, INPUT_BUFFER_SIZE - leftOver);  
  133.                 if( readBytes == 0 )  
  134.                     return 0;  
  135.                 inputBufferSize = leftOver + readBytes;  
  136.             }  
  137.             else  
  138.             {  
  139.                   
  140.                 int readBytes = file_read( mp3->file, mp3->inputBuffer, INPUT_BUFFER_SIZE);  
  141.                 if( readBytes == 0 )  
  142.                     return 0;  
  143.                 inputBufferSize = readBytes;  
  144.             }  
  145.   
  146.             mad_stream_buffer( &mp3->stream, mp3->inputBuffer, inputBufferSize );  
  147.             mp3->stream.error = MAD_ERROR_NONE;  
  148.   
  149.         }  
  150.   
  151.         if( mad_frame_decode( &mp3->frame, &mp3->stream ) )  
  152.         {  
  153.   
  154.             if( mp3->stream.error == MAD_ERROR_BUFLEN ||(MAD_RECOVERABLE(mp3->stream.error)))  
  155.                 continue;  
  156.             else  
  157.                 return 0;  
  158.         }  
  159.         else  
  160.             break;  
  161.     }  
  162.     while( 1 );  
  163.   
  164.     mad_timer_add( &mp3->timer, mp3->frame.header.duration );  
  165.     mad_synth_frame( &mp3->synth, &mp3->frame );  
  166.     mp3->leftSamples = mp3->synth.pcm.length;  
  167.     mp3->offset = 0;  
  168.   
  169.     return -1;  
  170. }  
  171.   
  172.   
  173.   
  174. int NativeMP3Decoder_readSamples(short *target, int size)  
  175. {  
  176.   
  177.     MP3FileHandle* mp3 = Handle;  
  178.     //short* target = (short*)env->GetDirectBufferAddress(buffer);   
  179.     int pos=0;  
  180.     int idx = 0;  
  181.     while( idx != size )  
  182.     {  
  183.         if( mp3->leftSamples > 0 )  
  184.         {  
  185.             for( ; idx < size && mp3->offset < mp3->synth.pcm.length; mp3->leftSamples--, mp3->offset++ )  
  186.             {  
  187.                 int value = fixedToShort(mp3->synth.pcm.samples[0][mp3->offset]);  
  188.   
  189.                 if( MAD_NCHANNELS(&mp3->frame.header) == 2 )  
  190.                 {  
  191.                     value += fixedToShort(mp3->synth.pcm.samples[1][mp3->offset]);  
  192.                     value /= 2;  
  193.                 }  
  194.   
  195.                 target[idx++] = value;  
  196.             }  
  197.         }  
  198.         else  
  199.         {  
  200.               
  201.             pos = file_seek( mp3->file, 0, SEEK_CUR);  
  202.   
  203.             int result = readNextFrame( mp3);  
  204.             if( result == 0 )  
  205.                 return 0;  
  206.         }  
  207.   
  208.     }  
  209.   /*  if(pos > mp3->fileStartPos + mp3->size) 
  210.     { 
  211.          
  212.         __android_log_print(ANDROID_LOG_INFO, TAG, "*****return -1**\n"); 
  213.         return -1; 
  214.     } 
  215. */  
  216.     if( idx > size )  
  217.         return 0;  
  218.   
  219.     //return size;   
  220.     return pos;  
  221.   
  222. }  
  223.   
  224. int NativeMP3Decoder_getAduioSamplerate()  
  225. {  
  226.     return g_Samplerate;  
  227.   
  228. }  
  229.   
  230.   
  231. void  NativeMP3Decoder_closeAduioFile()  
  232. {  
  233.     if( Handle != 0 )  
  234.     {  
  235.         closeHandle();  
  236.         Handle = 0;  
  237.     }  
  238. }  
#define TAG "NativeMP3Decoder"


#include "FileSystem.h"

#include "Mad.h"
#include "NativeMP3Decoder.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <android/log.h>




#define SHRT_MAX (32767)
#define INPUT_BUFFER_SIZE   (8192/4)
#define OUTPUT_BUFFER_SIZE  8192 /* Must be an integer multiple of 4. */

//int g_size;

extern int file_open(const char *filename, int flags);
extern int file_read(T_pFILE fd, unsigned char *buf, int size);
extern int file_write(T_pFILE fd, unsigned char *buf, int size);
extern int64_t file_seek(T_pFILE fd, int64_t pos, int whence);
extern int file_close(T_pFILE fd);

/**
 * Struct holding the pointer to a wave file.
 */
typedef struct
{
    int size;
    int64_t fileStartPos;
    T_pFILE file;
    struct mad_stream stream;
    struct mad_frame frame;
    struct mad_synth synth;
    mad_timer_t timer;
    int leftSamples;
    int offset;
    unsigned char inputBuffer[INPUT_BUFFER_SIZE];
} MP3FileHandle;


/** static WaveFileHandle array **/
static inline int readNextFrame( MP3FileHandle* mp3 );

static MP3FileHandle* Handle;
unsigned int g_Samplerate;

/**
 * Seeks a free handle in the handles array and returns its index or -1 if no handle could be found
 */

static inline void closeHandle()
{
    file_close( Handle->file);
    mad_synth_finish(&Handle->synth);
    mad_frame_finish(&Handle->frame);
    mad_stream_finish(&Handle->stream);
    free(Handle);
    Handle = NULL;
}

static inline signed short fixedToShort(mad_fixed_t Fixed)
{
    if(Fixed>=MAD_F_ONE)
        return(SHRT_MAX);
    if(Fixed<=-MAD_F_ONE)
        return(-SHRT_MAX);

    Fixed=Fixed>>(MAD_F_FRACBITS-15);
    return((signed short)Fixed);
}


int  NativeMP3Decoder_init(char * filepath,unsigned long start/*,unsigned long size*/)
{

    __android_log_print(ANDROID_LOG_INFO, TAG, "start = %d*******\n",start);

   // __android_log_print(ANDROID_LOG_INFO, TAG, "size = %d*******\n",size);


    //g_size=size;


    T_pFILE fileHandle = file_open( filepath, _FMODE_READ);
    if( fileHandle == 0 )
        return -1;

    MP3FileHandle* mp3Handle = (MP3FileHandle*)malloc(sizeof(MP3FileHandle));
    memset(mp3Handle, 0, sizeof(MP3FileHandle));
    mp3Handle->file = fileHandle;


   // mp3Handle->size = size;
    mp3Handle->fileStartPos= start;

    file_seek( mp3Handle->file, start, SEEK_SET);

    mad_stream_init(&mp3Handle->stream);
    mad_frame_init(&mp3Handle->frame);
    mad_synth_init(&mp3Handle->synth);
    mad_timer_reset(&mp3Handle->timer);

    Handle = mp3Handle;


    readNextFrame( Handle );

    g_Samplerate = Handle->frame.header.samplerate;
    return 1;
}

static inline int readNextFrame( MP3FileHandle* mp3 )
{
    do
    {
        if( mp3->stream.buffer == 0 || mp3->stream.error == MAD_ERROR_BUFLEN )
        {
            int inputBufferSize = 0;

            if( mp3->stream.next_frame != 0 )
            {

                int leftOver = mp3->stream.bufend - mp3->stream.next_frame;
                int i;
                for(  i= 0; i < leftOver; i++ )
                    mp3->inputBuffer[i] = mp3->stream.next_frame[i];
                int readBytes = file_read( mp3->file, mp3->inputBuffer + leftOver, INPUT_BUFFER_SIZE - leftOver);
                if( readBytes == 0 )
                    return 0;
                inputBufferSize = leftOver + readBytes;
            }
            else
            {
                
                int readBytes = file_read( mp3->file, mp3->inputBuffer, INPUT_BUFFER_SIZE);
                if( readBytes == 0 )
                    return 0;
                inputBufferSize = readBytes;
            }

            mad_stream_buffer( &mp3->stream, mp3->inputBuffer, inputBufferSize );
            mp3->stream.error = MAD_ERROR_NONE;

        }

        if( mad_frame_decode( &mp3->frame, &mp3->stream ) )
        {

            if( mp3->stream.error == MAD_ERROR_BUFLEN ||(MAD_RECOVERABLE(mp3->stream.error)))
                continue;
            else
                return 0;
        }
        else
            break;
    }
    while( 1 );

    mad_timer_add( &mp3->timer, mp3->frame.header.duration );
    mad_synth_frame( &mp3->synth, &mp3->frame );
    mp3->leftSamples = mp3->synth.pcm.length;
    mp3->offset = 0;

    return -1;
}



int NativeMP3Decoder_readSamples(short *target, int size)
{

    MP3FileHandle* mp3 = Handle;
    //short* target = (short*)env->GetDirectBufferAddress(buffer);
    int pos=0;
    int idx = 0;
    while( idx != size )
    {
        if( mp3->leftSamples > 0 )
        {
            for( ; idx < size && mp3->offset < mp3->synth.pcm.length; mp3->leftSamples--, mp3->offset++ )
            {
                int value = fixedToShort(mp3->synth.pcm.samples[0][mp3->offset]);

                if( MAD_NCHANNELS(&mp3->frame.header) == 2 )
                {
                    value += fixedToShort(mp3->synth.pcm.samples[1][mp3->offset]);
                    value /= 2;
                }

                target[idx++] = value;
            }
        }
        else
        {
            
            pos = file_seek( mp3->file, 0, SEEK_CUR);

            int result = readNextFrame( mp3);
            if( result == 0 )
                return 0;
        }

    }
  /*  if(pos > mp3->fileStartPos + mp3->size)
    {
        
        __android_log_print(ANDROID_LOG_INFO, TAG, "*****return -1**\n");
        return -1;
    }
*/
    if( idx > size )
        return 0;

    //return size;
    return pos;

}

int NativeMP3Decoder_getAduioSamplerate()
{
    return g_Samplerate;

}


void  NativeMP3Decoder_closeAduioFile()
{
    if( Handle != 0 )
    {
        closeHandle();
        Handle = 0;
    }
}






头文件声明

  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>   
  3. #include <stdlib.h>   
  4.   
  5.   
  6.   
  7. int    NativeMP3Decoder_init(char * filepath,unsigned long start/*,unsigned long size*/);  
  8.   
  9. int NativeMP3Decoder_readSamples(short *target, int size);  
  10.   
  11. void  NativeMP3Decoder_closeAduioFile();  
  12.   
  13. int NativeMP3Decoder_getAduioSamplerate();  
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <stdlib.h>



int    NativeMP3Decoder_init(char * filepath,unsigned long start/*,unsigned long size*/);

int NativeMP3Decoder_readSamples(short *target, int size);

void  NativeMP3Decoder_closeAduioFile();

int NativeMP3Decoder_getAduioSamplerate();



2.2、编写JNI调用代码,往上提供接口

  1. #define TAG "native_libmad"   
  2.   
  3.   
  4. #include "FileSystem.h"   
  5. #include <stdlib.h>   
  6. #include <jni.h>   
  7. #include <android/log.h>   
  8.   
  9.   
  10.   
  11.    
  12.  extern int NativeMP3Decoder_readSamples( short *target, int size);  
  13.    
  14.  extern void  NativeMP3Decoder_closeAduioFile();  
  15.    
  16.  extern int NativeMP3Decoder_getAduioSamplerate();  
  17.    
  18.  extern int NativeMP3Decoder_init(char * filepath,unsigned long start);  
  19.   
  20.   
  21.   
  22.  jint Java_com_conowen_libmad_NativeMP3Decoder_initAudioPlayer(JNIEnv *env, jobject obj, jstring file,jint startAddr)  
  23. {  
  24.       
  25.     char* fileString = (*env)->GetStringUTFChars(env,file, NULL);  
  26.       
  27.     return  NativeMP3Decoder_init(fileString,startAddr);  
  28.   
  29. }  
  30.   
  31.  jint Java_com_conowen_libmad_NativeMP3Decoder_getAudioBuf(JNIEnv *env, jobject obj ,jshortArray audioBuf,jint len)  
  32. {  
  33.     int bufsize = 0;  
  34.     int ret = 0;  
  35.     if (audioBuf != NULL) {  
  36.         bufsize = (*env)->GetArrayLength(env, audioBuf);  
  37.         jshort *_buf = (*env)->GetShortArrayElements(env, audioBuf, 0);  
  38.         memset(_buf, 0, bufsize*2);  
  39.         ret = NativeMP3Decoder_readSamples(_buf, len);  
  40.         (*env)->ReleaseShortArrayElements(env, audioBuf, _buf, 0);  
  41.     }  
  42.     else{  
  43.   
  44.             __android_log_print(ANDROID_LOG_DEBUG, TAG, "getAudio failed");  
  45.         }  
  46.     return ret;  
  47. }  
  48.    
  49.  jint Java_com_conowen_libmad_NativeMP3Decoder_getAudioSamplerate()  
  50. {  
  51.     return NativeMP3Decoder_getAduioSamplerate();  
  52. }  
  53.   
  54.   
  55.  void Java_com_conowen_libmad_NativeMP3Decoder_closeAduioFile( )  
  56.   
  57. {  
  58.     NativeMP3Decoder_closeAduioFile();  
  59.   
  60. }  
#define TAG "native_libmad"


#include "FileSystem.h"
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>



 
 extern int NativeMP3Decoder_readSamples( short *target, int size);
 
 extern void  NativeMP3Decoder_closeAduioFile();
 
 extern int NativeMP3Decoder_getAduioSamplerate();
 
 extern int NativeMP3Decoder_init(char * filepath,unsigned long start);



 jint Java_com_conowen_libmad_NativeMP3Decoder_initAudioPlayer(JNIEnv *env, jobject obj, jstring file,jint startAddr)
{
    
    char* fileString = (*env)->GetStringUTFChars(env,file, NULL);
    
    return  NativeMP3Decoder_init(fileString,startAddr);

}

 jint Java_com_conowen_libmad_NativeMP3Decoder_getAudioBuf(JNIEnv *env, jobject obj ,jshortArray audioBuf,jint len)
{
    int bufsize = 0;
    int ret = 0;
    if (audioBuf != NULL) {
        bufsize = (*env)->GetArrayLength(env, audioBuf);
        jshort *_buf = (*env)->GetShortArrayElements(env, audioBuf, 0);
        memset(_buf, 0, bufsize*2);
        ret = NativeMP3Decoder_readSamples(_buf, len);
        (*env)->ReleaseShortArrayElements(env, audioBuf, _buf, 0);
    }
    else{

            __android_log_print(ANDROID_LOG_DEBUG, TAG, "getAudio failed");
        }
    return ret;
}
 
 jint Java_com_conowen_libmad_NativeMP3Decoder_getAudioSamplerate()
{
    return NativeMP3Decoder_getAduioSamplerate();
}


 void Java_com_conowen_libmad_NativeMP3Decoder_closeAduioFile( )

{
    NativeMP3Decoder_closeAduioFile();

}


2.3、文件读写操作


  1. #include <unistd.h>  
  2. #include <sys/stat.h>  
  3. #include <sys/time.h>  
  4. #include <sys/types.h>  
  5. #include <stdlib.h>  
  6. #include <fcntl.h>  
  7. #include"FileSystem.h"  
  8.   
  9.  int file_open(const char *filename, int flags)  
  10. {  
  11. int access;  
  12.     T_pFILE fd = 0;  
  13.     if (flags ==  _CREATE) {  
  14.         access = O_CREAT | O_TRUNC | O_RDWR;  
  15.     } else if (flags == _WRONLY) {  
  16.         access = O_CREAT | O_TRUNC | O_WRONLY;  
  17.     } else if (flags == _RDONLY){  
  18.         access = O_RDONLY;  
  19.     } else if (flags == _RDWR){  
  20.         access = O_RDWR;  
  21.     } else{  
  22.         return -1;  
  23.     }  
  24.       
  25. #ifdef O_BINARY  
  26.     access |= O_BINARY;  
  27. #endif  
  28.     fd = open(filename, access, 0666);  
  29.     if (fd == -1)  
  30.         return -1;  
  31.     return fd;  
  32. }  
  33.   
  34. int file_read(T_pFILE fd, unsigned char *buf, int size)  
  35. {  
  36.       
  37.     return read(fd, buf, size);  
  38. }  
  39.   
  40. int file_write(T_pFILE fd, unsigned char *buf, int size)  
  41. {  
  42.       
  43.     return write(fd, buf, size);  
  44. }  
  45.   
  46.   
  47. int64_t file_seek(T_pFILE fd, int64_t pos, int whence)  
  48. {  
  49.       
  50.     if (whence == 0x10000) {  
  51.         struct stat st;  
  52.         int ret = fstat(fd, &st);  
  53.         return ret < 0 ? -1 : st.st_size;  
  54.     }  
  55.     return lseek(fd, pos, whence);  
  56. }  
  57.   
  58. int file_close(T_pFILE fd)  
  59. {  
  60.      
  61.     return close(fd);  
  62. }  
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include"FileSystem.h"

 int file_open(const char *filename, int flags)
{
int access;
    T_pFILE fd = 0;
    if (flags ==  _CREATE) {
        access = O_CREAT | O_TRUNC | O_RDWR;
    } else if (flags == _WRONLY) {
        access = O_CREAT | O_TRUNC | O_WRONLY;
    } else if (flags == _RDONLY){
        access = O_RDONLY;
    } else if (flags == _RDWR){
     	access = O_RDWR;
    } else{
    	return -1;
    }
	
#ifdef O_BINARY
    access |= O_BINARY;
#endif
    fd = open(filename, access, 0666);
    if (fd == -1)
        return -1;
    return fd;
}

int file_read(T_pFILE fd, unsigned char *buf, int size)
{
    
    return read(fd, buf, size);
}

int file_write(T_pFILE fd, unsigned char *buf, int size)
{
    
    return write(fd, buf, size);
}


int64_t file_seek(T_pFILE fd, int64_t pos, int whence)
{
    
    if (whence == 0x10000) {
        struct stat st;
        int ret = fstat(fd, &st);
        return ret < 0 ? -1 : st.st_size;
    }
    return lseek(fd, pos, whence);
}

int file_close(T_pFILE fd)
{
   
    return close(fd);
}

头文件

  1. #include <stdlib.h>  
  2.   
  3. typedef    signed long            T_S32;      /* signed 32 bit integer */  
  4.   
  5.   
  6. #define T_pFILE         T_S32  
  7. #define     T_hFILE             T_S32  
  8.   
  9.   
  10.   
  11.   
  12.   
  13.   
  14. #define _CREATE 0//"wb+"//0   
  15. #define _RDONLY 1//"rb" // 1   
  16. #define _WRONLY 2//"wb"// 2   
  17. #define _RDWR   3//"rb+"// 3   
  18.   
  19.   
  20.   
  21. #define _FMODE_READ     _RDONLY  
  22. #define _FMODE_WRITE    _WRONLY  
  23. #define _FMODE_CREATE   _CREATE  
  24. #define _FMODE_OVERLAY   _RDWR    
  25.   
  26.   
  27. #define _FSEEK_CURRENT  1  
  28. #define _FSEEK_END      2  
  29. #define _FSEEK_SET      0  
  30. #define _FOPEN_FAIL     -1  
  31.   
  32.   
  33. #define SEEK_CURRENT  1  
  34. #define SEEK_CUR  1  
  35. #define SEEK_END      2  
  36. #define SEEK_SET      0  
  37.   
  38. #define FS_SEEK_SET   0  
#include <stdlib.h>

typedef    signed long            T_S32;      /* signed 32 bit integer */


#define T_pFILE 		T_S32
#define     T_hFILE             T_S32






#define _CREATE 0//"wb+"//0
#define _RDONLY 1//"rb" // 1
#define _WRONLY 2//"wb"// 2
#define _RDWR   3//"rb+"// 3



#define _FMODE_READ     _RDONLY
#define _FMODE_WRITE    _WRONLY
#define _FMODE_CREATE   _CREATE
#define _FMODE_OVERLAY   _RDWR  


#define _FSEEK_CURRENT  1
#define _FSEEK_END      2
#define _FSEEK_SET      0
#define _FOPEN_FAIL     -1


#define SEEK_CURRENT  1
#define SEEK_CUR  1
#define SEEK_END      2
#define SEEK_SET      0

#define FS_SEEK_SET   0






把上述两个c文件,加入Android文件编译即可生成。90K左右
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值