Changeset 411
- Timestamp:
- 10/31/08 00:20:05 (16 years ago)
- Location:
- libmpc/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libmpc/trunk/include/mpc/mpcdec.h
r402 r411 62 62 63 63 typedef struct mpc_frame_info_t { 64 mpc_uint32_t samples; /// number of samples in the frame (counting once for multiple channels)65 mpc_int32_t bits; /// number of bits consumed by this frame (-1) if end of stream64 mpc_uint32_t samples; /// number of samples in the frame (counting once for multiple channels) 65 mpc_int32_t bits; /// number of bits consumed by this frame (-1) if end of stream 66 66 MPC_SAMPLE_FORMAT * buffer; /// frame samples buffer (size = samples * channels * sizeof(MPC_SAMPLE_FORMAT)) 67 mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer.67 mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer. 68 68 } mpc_frame_info; 69 70 typedef struct mpc_chap_info_t { 71 mpc_uint64_t sample; /// sample where the chapter starts 72 mpc_uint16_t gain; /// replaygain chapter value 73 mpc_uint16_t peak; /// peak chapter loudness level 74 mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter) 75 char * tag; /// pointer to an APEv2 tag without the preamble 76 } mpc_chap_info; 69 77 70 78 /// Initializes mpc decoder with the supplied stream info parameters. … … 128 136 /** 129 137 * Gets datas associated to a given chapter 130 * You can pass 0 for tag and tag_size if you don't needs the tag information131 138 * The chapter tag is an APEv2 tag without the preamble 132 139 * @param d pointer to a musepack demuxer 133 140 * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) 134 * @param tag will return a pointer to the chapter tag datas 135 * @param tag_size will be filed with the tag data size (0 if no tag for this chapter) 136 * @return the sample where the chapter starts 141 * @return the chapter information structure 137 142 */ 138 MPC_API mpc_ uint64_t mpc_demux_chap(mpc_demux * d, int chap_nb, char ** tag, mpc_uint_t * tag_size);143 MPC_API mpc_chap_info * mpc_demux_chap(mpc_demux * d, int chap_nb); 139 144 140 145 #ifdef __cplusplus -
libmpc/trunk/libmpcdec/internal.h
r402 r411 60 60 #define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box 61 61 62 typedef struct {63 mpc_uint64_t sample; /// sample where the chapter starts64 mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter)65 char * tag; /// pointer to an APEv2 tag without the preamble66 } mpc_chap_t;67 68 62 struct mpc_demux_t { 69 63 mpc_reader * r; … … 86 80 mpc_seek_t chap_pos; /// supposed position of the first chapter block 87 81 mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter) 88 mpc_chap_ t* chap; /// chapters position and tag82 mpc_chap_info * chap; /// chapters position and tag 89 83 90 84 }; -
libmpc/trunk/libmpcdec/mpc_demux.c
r407 r411 331 331 d->chap_nb++; 332 332 chap_size += size; 333 size = mpc_bits_get_size(&d->bits_reader, &chap_sample) ;333 size = mpc_bits_get_size(&d->bits_reader, &chap_sample) + 4; 334 334 chap_size += size; 335 335 tag_size += b.size - size; … … 340 340 if (d->chap_nb > 0) { 341 341 char * ptag; 342 d->chap = malloc(sizeof(mpc_chap_ t) * d->chap_nb + tag_size);342 d->chap = malloc(sizeof(mpc_chap_info) * d->chap_nb + tag_size); 343 343 ptag = (char*)(d->chap + d->chap_nb); 344 344 … … 347 347 while (memcmp(b.key, "CT", 2) == 0) { 348 348 mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0); 349 size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample); 349 size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample) + 4; 350 d->chap[i].gain = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); 351 d->chap[i].peak = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); 350 352 memcpy(ptag, d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3), b.size - size); 351 353 d->bits_reader.buff += b.size - size; … … 375 377 /** 376 378 * Gets datas associated to a given chapter 377 * You can pass 0 for tag and tag_size if you don't needs the tag information378 379 * The chapter tag is an APEv2 tag without the preamble 379 380 * @param d pointer to a musepack demuxer 380 381 * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) 381 * @param tag will return a pointer to the chapter tag datas 382 * @param tag_size will be filed with the tag data size (0 if no tag for this chapter) 383 * @return the sample where the chapter starts 382 * @return the chapter information structure 384 383 */ 385 mpc_ uint64_t mpc_demux_chap(mpc_demux * d, int chap_nb, char ** tag, mpc_uint_t * tag_size)384 mpc_chap_info * mpc_demux_chap(mpc_demux * d, int chap_nb) 386 385 { 387 386 if (d->chap_nb == -1) … … 389 388 if (chap_nb >= d->chap_nb || chap_nb < 0) 390 389 return 0; 391 if (tag != 0 && tag_size != 0) { 392 *tag = d->chap[chap_nb].tag; 393 *tag_size = d->chap[chap_nb].tag_size; 394 } 395 return d->chap[chap_nb].sample; 390 return &d->chap[chap_nb]; 396 391 } 397 392 -
libmpc/trunk/mpcchap/mpcchap.c
r408 r411 30 30 void Init_Tags ( void ); 31 31 int FinalizeTags ( FILE* fp, unsigned int Version, unsigned int flags ); 32 int addtag ( const char* key, size_t keylen, const char* value, size_t valuelen, int converttoutf8, int flags ); 32 int addtag ( const char* key, size_t keylen, const char* value, 33 size_t valuelen, int converttoutf8, int flags ); 33 34 #define TAG_NO_HEADER 1 34 35 #define TAG_NO_FOOTER 2 … … 39 40 #define atoll _atoi64 40 41 #endif 42 43 static const int Ptis[] = { PTI_TITLE, PTI_PERFORMER, PTI_SONGWRITER, PTI_COMPOSER, 44 PTI_ARRANGER, PTI_MESSAGE, PTI_GENRE}; 45 static char const * const APE_keys[] = {"Title", "Artist", "Songwriter", "Composer", 46 "Arranger", "Comment", "Genre"}; 41 47 42 48 static void usage(const char *exename) … … 77 83 int nchap = iniparser_getnsec(dict); 78 84 for (i = 0; i < nchap; i++) { 79 Init_Tags();80 int j, nitem, tag_len= 0;85 int j, nitem, ntags = 0, tag_len = 0; 86 mpc_uint16_t gain = 0, peak = 0; 81 87 char * chap_sec = iniparser_getsecname(dict, i); 82 88 mpc_int64_t chap_pos = atoll(chap_sec); 89 83 90 if (chap_pos > si->samples - si->beg_silence) 84 fprintf(stderr, "warning : chapter %i starts @ %lli after the end of the stream (%lli)\n", i + 1, chap_pos, si->samples - si->beg_silence); 91 fprintf(stderr, "warning : chapter %i starts @ %lli samples after the end of the stream (%lli)\n", 92 i + 1, chap_pos, si->samples - si->beg_silence); 93 94 Init_Tags(); 95 85 96 nitem = iniparser_getnkey(dict, i); 86 97 for (j = 0; j < nitem; j++) { … … 88 99 int key_len, item_len; 89 100 item_key = iniparser_getkeyname(dict, i, j, & item_value); 90 key_len = strlen(item_key); 91 item_len = strlen(item_value); 92 addtag(item_key, key_len, item_value, item_len, 0, 0); 93 tag_len += key_len + item_len; 101 if (strcmp(item_key, "gain") == 0) 102 gain = atoi(item_value); 103 else if (strcmp(item_key, "peak") == 0) 104 peak = atoi(item_value); 105 else { 106 key_len = strlen(item_key); 107 item_len = strlen(item_value); 108 addtag(item_key, key_len, item_value, item_len, 0, 0); 109 tag_len += key_len + item_len; 110 ntags++; 111 } 94 112 } 95 if (n item > 0) tag_len += 24 + nitem* 9;113 if (ntags > 0) tag_len += 24 + ntags * 9; 96 114 char block_header[12] = "CT"; 97 115 char sample_offset[10]; 98 116 int offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE); 99 tag_len = encodeSize(tag_len + offset_size + 2, block_header + 2, MPC_TRUE);117 tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE); 100 118 fwrite(block_header, 1, tag_len + 2, in_file); 101 119 fwrite(sample_offset, 1, offset_size, in_file); 120 sample_offset[0] = gain >> 8; 121 sample_offset[1] = gain & 0xFF; 122 sample_offset[2] = peak >> 8; 123 sample_offset[3] = peak & 0xFF; 124 fwrite(sample_offset, 1, 4, in_file); 102 125 FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE); 103 126 } … … 115 138 mpc_status add_chaps_cue(char * mpc_file, char * chap_file, mpc_demux * demux, mpc_streaminfo * si) 116 139 { 117 int Ptis[7] = { PTI_TITLE, PTI_PERFORMER, PTI_SONGWRITER, PTI_COMPOSER,118 PTI_ARRANGER, PTI_MESSAGE, PTI_GENRE};119 char * APE_keys[7] = {"Title", "Artist", "Songwriter", "Composer",120 "Arranger", "Comment", "Genre"};121 122 140 Cd *cd = 0; 123 141 int nchap, format = UNKNOWN; … … 155 173 156 174 if (chap_pos > si->samples - si->beg_silence) 157 fprintf(stderr, "warning : chapter %i starts @ %lli after the end of the stream (%lli)\n", i, chap_pos, si->samples - si->beg_silence); 175 fprintf(stderr, "warning : chapter %i starts @ %lli samples after the end of the stream (%lli)\n", 176 i, chap_pos, si->samples - si->beg_silence); 158 177 159 178 Init_Tags(); … … 168 187 169 188 for (j = 0; j < (sizeof(Ptis) / sizeof(*Ptis)); j++) { 170 char * item_key = APE_keys[j], * item_value;189 char const * item_key = APE_keys[j], * item_value; 171 190 item_value = cdtext_get (Ptis[j], cdtext); 172 191 if (item_value != 0) { … … 183 202 char sample_offset[10]; 184 203 int offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE); 185 tag_len = encodeSize(tag_len + offset_size + 2, block_header + 2, MPC_TRUE);204 tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE); 186 205 fwrite(block_header, 1, tag_len + 2, in_file); 187 206 fwrite(sample_offset, 1, offset_size, in_file); 207 fwrite("\0\0\0\0", 1, 4, in_file); // put unknow chapter gain / peak 188 208 FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE); 189 209 } … … 201 221 { 202 222 int i; 203 unsigned int tag_size;204 223 FILE * out_file; 205 char * tag;224 mpc_chap_info * chap; 206 225 207 226 if (chap_nb <= 0) … … 213 232 214 233 for (i = 0; i < chap_nb; i++) { 215 fprintf(out_file, "[%lli]\n", mpc_demux_chap(demux, i, &tag, &tag_size)); 216 if (tag_size > 0) { 234 chap = mpc_demux_chap(demux, i); 235 fprintf(out_file, "[%lli]\ngain=%i\npeak=%i\n", chap->sample, chap->gain, chap->peak); 236 if (chap->tag_size > 0) { 217 237 int item_count, j; 238 char const * tag = chap->tag; 218 239 item_count = tag[8] | (tag[9] << 8) | (tag[10] << 16) | (tag[11] << 24); 219 240 tag += 24;
Note: See TracChangeset
for help on using the changeset viewer.