PALMisLIFE 討論區

搜索
鹹魚爸魅力四射舞蹈教室
查看: 33906|回復: 1

把 Treo 680 的 Voice Memo 由 PDB 轉換為 AMR

[複製鏈接]

28

主題

0

好友

176

積分

  • TA的每日心情
    開心
    2011-10-7 19:08
  • 簽到天數: 1 天

    連續簽到: 1 天

    [LV.1]初來乍到

    文章
    198
    發表於 2009-6-10 11:20 |顯示全部樓層
    先前不知道 Treo 680 的 Voice Memo 不能在 PC 上播放,
    Palm 也沒有給同步的機制,
    結果錄了一堆聲音都沒有辦法轉寄給親友!

    參考網路上找到的 PDB format 寫了下面這段 C 程式,在 PC Linux 上使用 OK,
    我已經把先前錄的全轉為 AMR 格式了,
    AMR 要轉為 WAV 有免費的 Mobile AMR Converter
    1. #include <stdio.h>

    2. #define dmDBNameLength 32  /* 31 chars + 1 null terminator */

    3. #define PACKED __attribute__((packed))

    4. typedef unsigned char  UINT8;
    5. typedef unsigned short UINT16;
    6. typedef unsigned int   UINT32;

    7. typedef struct PACKED {
    8.    /* 8 bytes total */
    9.    UINT32 localChunkID;        /* offset to where record starts */
    10.    struct {
    11.        unsigned delete   : 1;
    12.        unsigned dirty    : 1;
    13.        unsigned busy     : 1;
    14.        unsigned secret   : 1;
    15.        unsigned category : 4;
    16.    } attributes;
    17.    UINT8 uniqueID[3];
    18. } RecordEntryType;

    19. typedef struct PACKED {
    20.    UINT32 nextRecordListID;
    21.    UINT16 numRecords;
    22. } RecordListType;

    23. typedef struct PACKED {
    24.    /* 78 bytes total */
    25.    UINT8          name[dmDBNameLength];
    26.    UINT16         attributes;
    27.    UINT16         version;
    28.    UINT32         createDate;
    29.    UINT32         modifyDate;
    30.    UINT32         lastBackupDate;
    31.    UINT32         modificationNumber;
    32.    UINT32         appInfoID;
    33.    UINT32         sortInfoID;
    34.    UINT8          type[4];
    35.    UINT8          creator[4];
    36.    UINT32         uniqueIdSeed;
    37.    RecordListType recordList;
    38. } pdb_header;

    39. typedef struct PACKED {
    40.    /* 8 bytes total */
    41.    UINT32 offset;
    42.    struct PACKED {
    43.        UINT32 delete   : 1;
    44.        UINT32 dirty    : 1;
    45.        UINT32 busy     : 1;
    46.        UINT32 secret   : 1;
    47.        UINT32 category : 4;
    48.    } attributes;
    49.    UINT8 uniqueID[3];
    50. } pdb_rec_header;

    51. typedef struct PACKED {
    52.    /* 8 bytes total */
    53.    UINT8 type[4];
    54.    UINT16 unknown;
    55.    UINT16 length;
    56. } pdb_rec_data_header;

    57. static UINT16 be2le16(UINT16 v)
    58. {
    59.    return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
    60. }

    61. static UINT32 be2le32(UINT32 v)
    62. {
    63.    return ((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8)
    64.           | ((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24);
    65. }

    66. int main(int argc, char *argv[])
    67. {
    68.    if (argc != 3) {
    69.        printf("%s PDBname AMRname\n", argv[0]);
    70.        return 0;
    71.    }

    72.    FILE *fpi;

    73.    fpi = fopen(argv[1], "r");
    74.    if (NULL == fpi) {
    75.        printf("$s open failed\n", argv[1]);
    76.        return 0;
    77.    }

    78.    pdb_header h;
    79.    int size;

    80.    size = fread(&h, sizeof h, 1, fpi);
    81.    if (1 != size) {
    82.        printf("pdb header read error\n");
    83.        return 0;
    84.    }

    85.    printf("name:    %s\n", h.name);
    86.    printf("attr:    0x%04X\n", h.attributes);
    87.    printf("ver:     0x%04X\n", h.version);
    88.    printf("c_time:  0x%08X\n", h.createDate);
    89.    printf("m_time:  0x%08X\n", h.modifyDate);
    90.    printf("b_time:  0x%08X\n", h.lastBackupDate);
    91.    printf("mod no:  0x%08X\n", h.modificationNumber);
    92.    printf("appid:   0x%08X\n", h.appInfoID);
    93.    printf("sortid:  0x%08X\n", h.sortInfoID);
    94.    printf("type:    %c%c%c%c\n", h.type[0], h.type[1], h.type[2], h.type[3]);
    95.    printf("creator: %c%c%c%c\n", h.creator[0], h.creator[1], h.creator[2], h.creator[3]);
    96.    printf("id seed: 0x%08X\n", h.uniqueIdSeed);
    97.    printf("nextRec: 0x%08X\n", h.recordList.nextRecordListID);
    98.    printf("rec nos: 0x%04X\n", be2le16(h.recordList.numRecords));

    99.    int recs = be2le16(h.recordList.numRecords);
    100.    int i;
    101.    FILE *fpo;

    102.    fpo = fopen(argv[2], "w");
    103.    if (NULL == fpo) {
    104.        printf("$s open failed\n", argv[2]);
    105.        return 0;
    106.    }

    107.    for (i = 0; i < recs; i++) {
    108.        pdb_rec_header rh;

    109.        fseek(fpi, sizeof h + sizeof rh * i, SEEK_SET);

    110.        size = fread(&rh, sizeof rh, 1, fpi);
    111.        if (1 != size) {
    112.            printf("record head %d read error\n", i);
    113.            return 0;
    114.        }

    115.        printf("record %4d\n", i);
    116.        printf("    offset %d\n", be2le32(rh.offset));
    117.        printf("    delete   : %d\n", rh.attributes.delete);
    118.        printf("    dirty    : %d\n", rh.attributes.dirty);
    119.        printf("    busy     : %d\n", rh.attributes.busy);
    120.        printf("    secret   : %d\n", rh.attributes.secret);
    121.        printf("    category : %d\n", rh.attributes.category);
    122.        printf("    uniqueID : %02X%02X%02X\n", rh.uniqueID[0], rh.uniqueID[1], rh.uniqueID[2]);

    123.        pdb_rec_data_header rdh;

    124.        fseek(fpi, be2le32(rh.offset), SEEK_SET);

    125.        size = fread(&rdh, sizeof rdh, 1, fpi);
    126.        if (1 != size) {
    127.            printf("record data head %d read error\n", i);
    128.            return 0;
    129.        }
    130.        rdh.length = be2le16(rdh.length);

    131. #define BUF_SIZE 65536
    132.        /* For 16-bit value, the maximum is 65536 */
    133.        char buf[BUF_SIZE];

    134.        size = fread(buf, 1, rdh.length, fpi);
    135.        if (size != rdh.length) {
    136.            printf("record data read error, should be %d bytes\n", rdh.length);
    137.            return 0;
    138.        }
    139.        size = fwrite(buf, 1, rdh.length, fpo);
    140.        if (size != rdh.length) {
    141.            printf("record data write error\n");
    142.            return 0;
    143.        }
    144.    }

    145.    fclose(fpi);
    146.    fclose(fpo);

    147.    return 0;
    148. }
    複製代碼
    已有 2 人評分分享 收起 理由
    joker + 3 編譯成功,去年錄的終於能在pc上撥了。
    haha + 10 挖塞!!

    總評分: 分享 + 13   查看全部評分

    494

    主題

    15

    好友

    8455

    積分

  • TA的每日心情
    開心
    2018-5-15 04:36
  • 簽到天數: 2485 天

    連續簽到: 27 天

    [LV.Master]伴壇終老

    文章
    1446
    發表於 2009-8-10 16:55 |顯示全部樓層
    可以提供.exe檔嗎?
    回復

    使用道具 舉報

    您需要登錄後才可以回帖 登錄 | 免費註冊

    與站長聯繫| PALMisLIFE 掌上生活      下載:更快、更棒、更好玩

    GMT+8, 2024-4-16 14:43 , Processed in 0.052734 second(s), 35 queries , Gzip On.

    Powered by Discuz!

    © 2001-2012 Comsenz Inc. style by eisdl

    回頂部