⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wma_parsenew.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:
/******************************************************************************
*
*  Copyright (C),2007, Fuzhou Rockchip Co.,Ltd.
*
*  File name :     wma_parse.c
*  Description:    得到wma歌曲的ID3信息
*  Remark:
*
*  History:
*           <author>      <time>     <version>       <desc>
*           Huweiguo     07/11/05      1.0
*
*******************************************************************************/
#if ((defined(BOARD)) || defined(ROCK_FS))

#include "include.h"
#include "wma_parseNew.h"

#ifdef  _MEIDA_SORT_NEW

#define MIN_OBJECT_SIZE     24
#define DATA_OBJECT_SIZE    50

#define LOAD_DWORD(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24) )
#define LOAD_WORD(p)  ((p)[0] | ((p)[1]<<8))

#define ECD_STRING 0

static unsigned char AsfHeaderObjectV0[16] =
{
    0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c
};

static unsigned char AsfContentDescriptionObjectV0[16] =
{
    0x33, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c
};

static unsigned char AsfExtendedContentDescObject[16] =
{
    0x40, 0xa4, 0xd0, 0xd2, 0x07, 0xe3, 0xd2, 0x11, 0x97, 0xf0, 0x0, 0xa0, 0xc9, 0x5e, 0xa8, 0x50
};

static unsigned short WM_AlbumTitle[13] =
{
    'W', 'M', '/', 'A', 'l', 'b', 'u', 'm', 'T', 'i', 't', 'l', 'e'
};

static unsigned short WM_Genre[8] =
{
    'W', 'M', '/', 'G', 'e', 'n', 'r', 'e'
};

int AP_FileSeek(AP_FILE *fhandle, long offset, int mode)
{
    return FSFileSeek((AP_FILE *)fhandle, offset, mode);
}

int AP_FileRead(unsigned char *buffer, long cbLen, AP_FILE *fhandle)
{
    return FSFileRead(buffer, cbLen, (AP_FILE *)fhandle);
}


int WMALoadExtendedContentDescObject(unsigned char* pObject, long currPacketOffset, long cbObject, WMA_ID3 *id3)
{
    long cbWanted;
    short cDescriptors = 0;
    short cbName, data_type, cbValue;
    long iCurrFileOffset;
    long iMaxFileOffset;
    int i;

    //assert (cbSize >= MIN_OBJECT_SIZE);
    iCurrFileOffset = currPacketOffset;
    iMaxFileOffset = iCurrFileOffset + cbObject - MIN_OBJECT_SIZE;

    // Get descriptor count
    cbWanted = sizeof(short);
    if (iCurrFileOffset + cbWanted > iMaxFileOffset)
    {
        return AP_FAIL;
    }

    cDescriptors = LOAD_WORD(pObject + iCurrFileOffset);
    iCurrFileOffset += cbWanted;

    // Read in each descriptor record
    for (i = 0; i < cDescriptors; i++)
    {
        int fAlbumFind = 0;
        int fGenreFind = 0;

        // Load in descriptor name length
        cbWanted = sizeof(short);
        if (iCurrFileOffset + cbWanted > iMaxFileOffset)
        {
            return AP_FAIL;
        }

        cbName = LOAD_WORD(pObject + iCurrFileOffset);
        iCurrFileOffset += cbWanted;

        // Load in descriptor name
        if (0 == memcmp(WM_AlbumTitle, pObject + iCurrFileOffset, sizeof(WM_AlbumTitle)))
        {
            fAlbumFind = 1; // 找到AlbumTitle,然后读出AlbumTitle
        }
        else if (0 == memcmp(WM_Genre, pObject + iCurrFileOffset, sizeof(WM_Genre)))
        {
            fGenreFind = 1; // 找到Genre 信息,
        }
        iCurrFileOffset += cbName;

        // Load in descriptor value type, and descriptor value length
        cbWanted = 2 * sizeof(short);
        if (iCurrFileOffset + cbWanted > iMaxFileOffset)
        {
            return AP_FAIL;
        }

        data_type = LOAD_WORD(pObject + iCurrFileOffset);
        cbValue = LOAD_WORD(pObject + iCurrFileOffset + sizeof(short));
        iCurrFileOffset += cbWanted;

        // Load in descriptor value
        if (ECD_STRING == data_type)
        {
            if (fAlbumFind)
            {
                cbWanted = cbValue > MAX_STRING_SIZE_CHAR ? MAX_STRING_SIZE_CHAR : cbValue;
                memcpy(id3->Album, pObject + iCurrFileOffset, cbWanted);
                cbWanted >>= 1; // char to wchar, so /2
                id3->Album[cbWanted-1] = 0; // null

                if (fGenreFind)
                    break;
            }
            else if (fGenreFind)
            {
                cbWanted = cbValue > MAX_STRING_SIZE_CHAR ? MAX_STRING_SIZE_CHAR : cbValue;
                memcpy(id3->Genre, pObject + iCurrFileOffset, cbWanted);
                cbWanted >>= 1; // char to wchar, so /2
                id3->Genre[cbWanted-1] = 0; // null

                if (fAlbumFind)
                    break;
            }

        }
        iCurrFileOffset += cbValue;
    } // for

    return AP_SUCESS;
}

int WMALoadContentDescriptionObject(unsigned char* pObject, long currPacketOffset, long cbObject, WMA_ID3 *id3)
{
    long iCurrFileOffset;
    long iMaxFileOffset;
    long cbWanted;
    short title_len, author_len;

    //assert (cbSize >= MIN_OBJECT_SIZE);
    iCurrFileOffset = currPacketOffset;
    iMaxFileOffset = iCurrFileOffset + cbObject - MIN_OBJECT_SIZE;

    cbWanted = 5 * sizeof(short);
    if (iCurrFileOffset + cbWanted > iMaxFileOffset)
    {
        return AP_FAIL;
    }

    title_len = LOAD_WORD(pObject + iCurrFileOffset);
    author_len = LOAD_WORD(pObject + iCurrFileOffset + sizeof(short));
    //copyright_len = LOAD_WORD(pData+iCurrFileOffset);
    //description_len = LOAD_WORD(pData+iCurrFileOffset);
    //rating_len = LOAD_WORD(pData+iCurrFileOffset);

    iCurrFileOffset += cbWanted;

    // Get Title
    cbWanted = title_len > MAX_STRING_SIZE_CHAR ? MAX_STRING_SIZE_CHAR : title_len;
    memcpy(id3->Title, pObject + iCurrFileOffset, cbWanted);
    cbWanted >>= 1; // char to wchar, so /2
    id3->Title[cbWanted-1] = 0; // null

    iCurrFileOffset += title_len;

    // Get Author
    cbWanted = author_len > MAX_STRING_SIZE_CHAR ? MAX_STRING_SIZE_CHAR : author_len;
    memcpy(id3->Author, pObject + iCurrFileOffset, cbWanted);
    cbWanted >>= 1;
    id3->Author[cbWanted-1] = 0; // null

    //assert(iCurrFileOffset == iMaxFileOffset);

    return AP_SUCESS;
}

#if 1
// 一次性打头文件都读出来
int WMAParseAsfHeader(AP_FILE *fhandle,  WMA_ID3 *id3)
{
    int wmarc;
    unsigned char *pObjId;
    unsigned char hdrObj[30];
    long objSize;
    long currPacketOffset, cbHeader, cbFirstPacketOffset;
    unsigned char *pHeader;
    int ContentOK = 0;

    //memset(id3, 0, sizeof(WMA_ID3));

    /* initialize the some state */

    currPacketOffset = 0;

    /* ASF Header Object */

    AP_FileRead(hdrObj, 30, (AP_FILE*)fhandle);

    if (0 != memcmp(AsfHeaderObjectV0, hdrObj, 16))
    {
        return AP_FAIL;
    }

    currPacketOffset += 16;
    cbHeader = LOAD_DWORD(&hdrObj[currPacketOffset]);
    cbFirstPacketOffset = cbHeader + DATA_OBJECT_SIZE;

    currPacketOffset = 30;

    pHeader = (unsigned char*)malloc(cbHeader);
    if (0 == pHeader)
    {
        return  AP_FAIL;
    }

    AP_FileRead(pHeader + currPacketOffset, cbHeader - currPacketOffset, (AP_FILE*)fhandle);

    /* Scan Header Objects */

    while (currPacketOffset < cbHeader)
    {
        if (ContentOK >= 2)
        {
            break; // 表示已经得到了ID3信息,没必要再继续解析
        }

        pObjId = pHeader + currPacketOffset;
        objSize = LOAD_DWORD(pObjId + 16);
        currPacketOffset += MIN_OBJECT_SIZE;

        if (0 == memcmp(AsfContentDescriptionObjectV0, pObjId, 16))
        {
            if (currPacketOffset + (objSize - MIN_OBJECT_SIZE) > cbFirstPacketOffset)
            {
                return AP_FAIL;
            }

            wmarc = WMALoadContentDescriptionObject(pHeader, currPacketOffset, objSize, id3);
            if (AP_SUCESS != wmarc)
            {
                return AP_FAIL;
            }
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
            ContentOK += 1;
        }
        else if (0 == memcmp(AsfExtendedContentDescObject, pObjId, 16))
        {
            if (currPacketOffset + (objSize - MIN_OBJECT_SIZE) > cbFirstPacketOffset)
            {
                return AP_FAIL;
            }

            wmarc = WMALoadExtendedContentDescObject(pHeader, currPacketOffset, objSize, id3);
            if (AP_SUCESS != wmarc)
            {
                return AP_FAIL;
            }
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
            ContentOK += 1;
        }
        else
        {
            /* skip over this object */
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
        }
    }

    if (0 != pHeader)
    {
        free(pHeader);
    }

    return AP_SUCESS;
}
#else
// 需要多少时读多少的内容
int WMAParseAsfHeader(AP_FILE *fhandle,  WMA_ID3 *id3)
{
    int wmarc;
    unsigned char *pObjId;
    unsigned char hdrObj[30];
    long objSize;
    long currPacketOffset, cbHeader, cbFirstPacketOffset;
    unsigned char *pHeader;
    int ContentOK = 0;

    memset(id3, 0, sizeof(ID3));

    /* initialize the some state */

    currPacketOffset = 0;

    /* ASF Header Object */

    AP_FileRead(hdrObj, 30, (AP_FILE*)fhandle);

    if (0 != memcmp(AsfHeaderObjectV0, hdrObj, 16))
    {
        return AP_FAIL;
    }

    currPacketOffset += 16;
    cbHeader = LOAD_DWORD(&hdrObj[currPacketOffset]);
    cbFirstPacketOffset = cbHeader + DATA_OBJECT_SIZE;

    currPacketOffset = 30;

    pHeader = (unsigned char*)malloc(cbHeader);
    if (0 == pHeader)
    {
        return  AP_FAIL;
    }

    /* Scan Header Objects */

    while (currPacketOffset < cbHeader)
    {
        if (ContentOK >= 2)
        {
            break; // 表示已经得到了ID3信息,没必要再继续解析
        }

        AP_FileSeek((AP_FILE*)fhandle, currPacketOffset, SEEK_SET);
        AP_FileRead(pHeader + currPacketOffset, MIN_OBJECT_SIZE, (AP_FILE*)fhandle);

        pObjId = pHeader + currPacketOffset;
        objSize = LOAD_DWORD(pObjId + 16);
        currPacketOffset += MIN_OBJECT_SIZE;

        if (0 == memcmp(AsfContentDescriptionObjectV0, pObjId, 16))
        {
            if (currPacketOffset + (objSize - MIN_OBJECT_SIZE) > cbFirstPacketOffset)
            {
                return AP_FAIL;
            }

            AP_FileRead(pHeader + currPacketOffset, objSize - MIN_OBJECT_SIZE, (AP_FILE*)fhandle);

            wmarc = WMALoadContentDescriptionObject(pHeader, currPacketOffset, objSize, id3);
            if (AP_SUCESS != wmarc)
            {
                return AP_FAIL;
            }
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
            ContentOK += 1;
        }
        else if (0 == memcmp(AsfExtendedContentDescObject, pObjId, 16))
        {
            if (currPacketOffset + (objSize - MIN_OBJECT_SIZE) > cbFirstPacketOffset)
            {
                return AP_FAIL;
            }

            AP_FileRead(pHeader + currPacketOffset, objSize - MIN_OBJECT_SIZE, (AP_FILE*)fhandle);

            wmarc = WMALoadExtendedContentDescObject(pHeader, currPacketOffset, objSize, id3);
            if (AP_SUCESS != wmarc)
            {
                return AP_FAIL;
            }
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
            ContentOK += 1;
        }
        else
        {
            /* skip over this object */
            currPacketOffset += objSize - MIN_OBJECT_SIZE;
        }
    }

    if (0 != pHeader)
    {
        free(pHeader);
    }

    return AP_SUCESS;
}

#endif

#endif
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -