PALMisLIFE 討論區
標題:
把 Treo 680 的 Voice Memo 由 PDB 轉換為 AMR
[列印本頁]
作者:
sun409
時間:
2009-6-10 11:20
標題:
把 Treo 680 的 Voice Memo 由 PDB 轉換為 AMR
先前不知道 Treo 680 的 Voice Memo 不能在 PC 上播放,
Palm 也沒有給同步的機制,
結果錄了一堆聲音都沒有辦法轉寄給親友!
參考網路上找到的 PDB format 寫了下面這段 C 程式,在 PC Linux 上使用 OK,
我已經把先前錄的全轉為 AMR 格式了,
AMR 要轉為 WAV 有免費的
Mobile AMR Converter
#include <stdio.h>
#define dmDBNameLength 32 /* 31 chars + 1 null terminator */
#define PACKED __attribute__((packed))
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef struct PACKED {
/* 8 bytes total */
UINT32 localChunkID; /* offset to where record starts */
struct {
unsigned delete : 1;
unsigned dirty : 1;
unsigned busy : 1;
unsigned secret : 1;
unsigned category : 4;
} attributes;
UINT8 uniqueID[3];
} RecordEntryType;
typedef struct PACKED {
UINT32 nextRecordListID;
UINT16 numRecords;
} RecordListType;
typedef struct PACKED {
/* 78 bytes total */
UINT8 name[dmDBNameLength];
UINT16 attributes;
UINT16 version;
UINT32 createDate;
UINT32 modifyDate;
UINT32 lastBackupDate;
UINT32 modificationNumber;
UINT32 appInfoID;
UINT32 sortInfoID;
UINT8 type[4];
UINT8 creator[4];
UINT32 uniqueIdSeed;
RecordListType recordList;
} pdb_header;
typedef struct PACKED {
/* 8 bytes total */
UINT32 offset;
struct PACKED {
UINT32 delete : 1;
UINT32 dirty : 1;
UINT32 busy : 1;
UINT32 secret : 1;
UINT32 category : 4;
} attributes;
UINT8 uniqueID[3];
} pdb_rec_header;
typedef struct PACKED {
/* 8 bytes total */
UINT8 type[4];
UINT16 unknown;
UINT16 length;
} pdb_rec_data_header;
static UINT16 be2le16(UINT16 v)
{
return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
}
static UINT32 be2le32(UINT32 v)
{
return ((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8)
| ((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24);
}
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("%s PDBname AMRname\n", argv[0]);
return 0;
}
FILE *fpi;
fpi = fopen(argv[1], "r");
if (NULL == fpi) {
printf("$s open failed\n", argv[1]);
return 0;
}
pdb_header h;
int size;
size = fread(&h, sizeof h, 1, fpi);
if (1 != size) {
printf("pdb header read error\n");
return 0;
}
printf("name: %s\n", h.name);
printf("attr: 0x%04X\n", h.attributes);
printf("ver: 0x%04X\n", h.version);
printf("c_time: 0x%08X\n", h.createDate);
printf("m_time: 0x%08X\n", h.modifyDate);
printf("b_time: 0x%08X\n", h.lastBackupDate);
printf("mod no: 0x%08X\n", h.modificationNumber);
printf("appid: 0x%08X\n", h.appInfoID);
printf("sortid: 0x%08X\n", h.sortInfoID);
printf("type: %c%c%c%c\n", h.type[0], h.type[1], h.type[2], h.type[3]);
printf("creator: %c%c%c%c\n", h.creator[0], h.creator[1], h.creator[2], h.creator[3]);
printf("id seed: 0x%08X\n", h.uniqueIdSeed);
printf("nextRec: 0x%08X\n", h.recordList.nextRecordListID);
printf("rec nos: 0x%04X\n", be2le16(h.recordList.numRecords));
int recs = be2le16(h.recordList.numRecords);
int i;
FILE *fpo;
fpo = fopen(argv[2], "w");
if (NULL == fpo) {
printf("$s open failed\n", argv[2]);
return 0;
}
for (i = 0; i < recs; i++) {
pdb_rec_header rh;
fseek(fpi, sizeof h + sizeof rh * i, SEEK_SET);
size = fread(&rh, sizeof rh, 1, fpi);
if (1 != size) {
printf("record head %d read error\n", i);
return 0;
}
printf("record %4d\n", i);
printf(" offset %d\n", be2le32(rh.offset));
printf(" delete : %d\n", rh.attributes.delete);
printf(" dirty : %d\n", rh.attributes.dirty);
printf(" busy : %d\n", rh.attributes.busy);
printf(" secret : %d\n", rh.attributes.secret);
printf(" category : %d\n", rh.attributes.category);
printf(" uniqueID : %02X%02X%02X\n", rh.uniqueID[0], rh.uniqueID[1], rh.uniqueID[2]);
pdb_rec_data_header rdh;
fseek(fpi, be2le32(rh.offset), SEEK_SET);
size = fread(&rdh, sizeof rdh, 1, fpi);
if (1 != size) {
printf("record data head %d read error\n", i);
return 0;
}
rdh.length = be2le16(rdh.length);
#define BUF_SIZE 65536
/* For 16-bit value, the maximum is 65536 */
char buf[BUF_SIZE];
size = fread(buf, 1, rdh.length, fpi);
if (size != rdh.length) {
printf("record data read error, should be %d bytes\n", rdh.length);
return 0;
}
size = fwrite(buf, 1, rdh.length, fpo);
if (size != rdh.length) {
printf("record data write error\n");
return 0;
}
}
fclose(fpi);
fclose(fpo);
return 0;
}
複製代碼
作者:
james2mac
時間:
2009-8-10 16:55
可以提供.exe檔嗎?
歡迎光臨 PALMisLIFE 討論區 (http://f.pil.tw/)
Powered by Discuz! X2.5