Mercurial > audlegacy-plugins
comparison src/demac/plugin.c @ 2516:d3597870a64f
switch to AUDDBG
| author | Eugene Zagidullin <e.asphyx@gmail.com> |
|---|---|
| date | Sun, 06 Apr 2008 17:30:22 +0400 |
| parents | ed6c81bd9016 |
| children | bd3a24b39058 |
comparison
equal
deleted
inserted
replaced
| 2515:e732490b4dbf | 2516:d3597870a64f |
|---|---|
| 65 static unsigned long seek_to_msec=(unsigned long)-1; /* -1 == not needed */ | 65 static unsigned long seek_to_msec=(unsigned long)-1; /* -1 == not needed */ |
| 66 | 66 |
| 67 static InputPlugin demac_ip; | 67 static InputPlugin demac_ip; |
| 68 static GtkWidget *about_window = NULL; | 68 static GtkWidget *about_window = NULL; |
| 69 | 69 |
| 70 #ifdef DEBUG | 70 #ifdef AUD_DEBUG |
| 71 # include "crc.c" | 71 # include "crc.c" |
| 72 #endif | 72 #endif |
| 73 | 73 |
| 74 static gboolean demac_probe_vfs(char *filename, VFSFile* input_file) { | 74 static gboolean demac_probe_vfs(char *filename, VFSFile* input_file) { |
| 75 APEContext *ctx; | 75 APEContext *ctx; |
| 116 unsigned long local_seek_to; | 116 unsigned long local_seek_to; |
| 117 APEContext *ctx = NULL; | 117 APEContext *ctx = NULL; |
| 118 APEDecoderContext *dec = NULL; | 118 APEDecoderContext *dec = NULL; |
| 119 int decoded_bytes; | 119 int decoded_bytes; |
| 120 int pkt_size, bytes_used; | 120 int pkt_size, bytes_used; |
| 121 #ifdef DEBUG | 121 #ifdef AUD_DEBUG |
| 122 uint32_t frame_crc; | 122 uint32_t frame_crc; |
| 123 #endif | 123 #endif |
| 124 | 124 |
| 125 if ((vfd = aud_vfs_fopen(pb->filename, "r")) == NULL) { | 125 if ((vfd = aud_vfs_fopen(pb->filename, "r")) == NULL) { |
| 126 #ifdef DEBUG | 126 AUDDBG("** demac: plugin.c: Error opening URI: %s\n", pb->filename); |
| 127 fprintf(stderr, "** demac: plugin.c: Error opening URI: %s\n", pb->filename); | |
| 128 #endif | |
| 129 pb->error = TRUE; | 127 pb->error = TRUE; |
| 130 goto cleanup; | 128 goto cleanup; |
| 131 } | 129 } |
| 132 | 130 |
| 133 ctx = calloc(sizeof(APEContext), 1); | 131 ctx = calloc(sizeof(APEContext), 1); |
| 134 if(ape_read_header(ctx, vfd, 0) < 0) { | 132 if(ape_read_header(ctx, vfd, 0) < 0) { |
| 135 pb->error = TRUE; | 133 pb->error = TRUE; |
| 136 #ifdef DEBUG | 134 AUDDBG("** demac: plugin.c: Cannot parse APE header or unsupported format: %s\n", pb->filename); |
| 137 fprintf(stderr, "** demac: plugin.c: Cannot parse APE header or unsupported format: %s\n", pb->filename); | |
| 138 #endif | |
| 139 goto cleanup; | 135 goto cleanup; |
| 140 } | 136 } |
| 141 | 137 |
| 142 dec = calloc(sizeof(APEDecoderContext), 1); | 138 dec = calloc(sizeof(APEDecoderContext), 1); |
| 143 if(ape_decode_init(dec, ctx) < 0) { | 139 if(ape_decode_init(dec, ctx) < 0) { |
| 144 pb->error = TRUE; | 140 pb->error = TRUE; |
| 145 #ifdef DEBUG | 141 AUDDBG("** demac: plugin.c: Error initializing decoder\n"); |
| 146 fprintf(stderr, "** demac: plugin.c: Error initializing decoder\n"); | |
| 147 #endif | |
| 148 goto cleanup; | 142 goto cleanup; |
| 149 } | 143 } |
| 150 | 144 |
| 151 frame_buf = malloc(ctx->max_packet_size); | 145 frame_buf = malloc(ctx->max_packet_size); |
| 152 | 146 |
| 153 #ifdef DEBUG | 147 AUDDBG("** demac: plugin.c: Duration: %u msec\n", ctx->duration); |
| 154 fprintf(stderr, "** demac: plugin.c: Duration: %u msec\n", ctx->duration); | |
| 155 #endif | |
| 156 | 148 |
| 157 if(!pb->output->open_audio(FMT_S16_LE, ctx->samplerate, ctx->channels)) { | 149 if(!pb->output->open_audio(FMT_S16_LE, ctx->samplerate, ctx->channels)) { |
| 158 pb->error = TRUE; | 150 pb->error = TRUE; |
| 159 #ifdef DEBUG | 151 AUDDBG("** demac: plugin.c: Cannot open audio.\n"); |
| 160 fprintf(stderr, "** demac: plugin.c: Cannot open audio.\n"); | |
| 161 #endif | |
| 162 goto cleanup; | 152 goto cleanup; |
| 163 } | 153 } |
| 164 | 154 |
| 165 audio_opened = 1; | 155 audio_opened = 1; |
| 166 | 156 |
| 197 /* reset decoder */ | 187 /* reset decoder */ |
| 198 dec->samples = 0; | 188 dec->samples = 0; |
| 199 } | 189 } |
| 200 | 190 |
| 201 ape_read_packet(ctx, vfd, frame_buf, &pkt_size); | 191 ape_read_packet(ctx, vfd, frame_buf, &pkt_size); |
| 202 #ifdef DEBUG | 192 #ifdef AUD_DEBUG |
| 203 assert(pkt_size <= ctx->max_packet_size); | 193 assert(pkt_size <= ctx->max_packet_size); |
| 204 frame_crc = ape_initcrc(); | 194 frame_crc = ape_initcrc(); |
| 205 #endif | 195 #endif |
| 206 bytes_used = 0; | 196 bytes_used = 0; |
| 207 | |
| 208 /*#ifdef DEBUG | |
| 209 fprintf(stderr, "frame %d, %d samples, offset %d, size %d\n", ctx->currentframe-1, | |
| 210 *((uint32_t*)frame_buf), *((uint32_t*)(frame_buf+4)), pkt_size); | |
| 211 #endif*/ | |
| 212 | 197 |
| 213 /* Decode the frame a chunk at a time */ | 198 /* Decode the frame a chunk at a time */ |
| 214 while (playing && (bytes_used != pkt_size) && (local_seek_to == -1)) | 199 while (playing && (bytes_used != pkt_size) && (local_seek_to == -1)) |
| 215 { | 200 { |
| 216 g_mutex_lock(demac_mutex); | 201 g_mutex_lock(demac_mutex); |
| 228 | 213 |
| 229 if(local_seek_to != -1) break; | 214 if(local_seek_to != -1) break; |
| 230 | 215 |
| 231 /* Write audio data */ | 216 /* Write audio data */ |
| 232 pb->pass_audio(pb, FMT_S16_LE, ctx->channels, decoded_bytes, wav, &playing); | 217 pb->pass_audio(pb, FMT_S16_LE, ctx->channels, decoded_bytes, wav, &playing); |
| 233 #if DEBUG | 218 #ifdef AUD_DEBUG |
| 234 frame_crc = ape_updatecrc(wav, decoded_bytes, frame_crc); | 219 frame_crc = ape_updatecrc(wav, decoded_bytes, frame_crc); |
| 235 #endif | 220 #endif |
| 236 | 221 |
| 237 } | 222 } |
| 238 | 223 |
| 239 #if DEBUG | 224 #ifdef AUD_DEBUG |
| 240 frame_crc = ape_finishcrc(frame_crc); | 225 frame_crc = ape_finishcrc(frame_crc); |
| 241 | 226 |
| 242 if (dec->CRC != frame_crc) { | 227 if (dec->CRC != frame_crc) { |
| 243 fprintf(stderr, "** demac: plugin.c: CRC error in frame %d\n", ctx->currentframe-1); | 228 AUDDBG("** demac: plugin.c: CRC error in frame %d\n", ctx->currentframe-1); |
| 244 } | 229 } |
| 245 #endif | 230 #endif |
| 246 } | 231 } |
| 247 | 232 |
| 248 cleanup: | 233 cleanup: |
| 257 if(wav) free(wav); | 242 if(wav) free(wav); |
| 258 if(frame_buf) free(frame_buf); | 243 if(frame_buf) free(frame_buf); |
| 259 if(ctx) {ape_read_close(ctx); free(ctx);} | 244 if(ctx) {ape_read_close(ctx); free(ctx);} |
| 260 if(vfd) aud_vfs_fclose(vfd); | 245 if(vfd) aud_vfs_fclose(vfd); |
| 261 | 246 |
| 262 #ifdef DEBUG | 247 AUDDBG("** demac: plugin.c: decoding loop finished\n"); |
| 263 fprintf(stderr, "** demac: plugin.c: decoding loop finished\n"); | |
| 264 #endif | |
| 265 | 248 |
| 266 return NULL; | 249 return NULL; |
| 267 } | 250 } |
| 268 | 251 |
| 269 static void demac_stop(InputPlayback *pb) | 252 static void demac_stop(InputPlayback *pb) |
| 274 | 257 |
| 275 if (playing) { | 258 if (playing) { |
| 276 g_mutex_lock(demac_mutex); | 259 g_mutex_lock(demac_mutex); |
| 277 pb->playing = 0; | 260 pb->playing = 0; |
| 278 g_mutex_unlock(demac_mutex); | 261 g_mutex_unlock(demac_mutex); |
| 279 #ifdef DEBUG | 262 AUDDBG("** demac: plugin.c: waiting for thread finished\n"); |
| 280 fprintf(stderr, "** demac: plugin.c: waiting for thread finished\n"); | |
| 281 #endif | |
| 282 //g_thread_join(pb->thread); | |
| 283 /* pb->thread is useless if input plugin initialized from **terrible** cue-sheet plugin */ | |
| 284 g_thread_join(pb_thread); | 263 g_thread_join(pb_thread); |
| 285 #ifdef DEBUG | 264 AUDDBG("** demac: plugin.c: thread finished\n"); |
| 286 fprintf(stderr, "** demac: plugin.c: thread finished\n"); | |
| 287 #endif | |
| 288 } | 265 } |
| 289 } | 266 } |
| 290 | 267 |
| 291 static void demac_pause(InputPlayback *pb, short paused) { | 268 static void demac_pause(InputPlayback *pb, short paused) { |
| 292 pb->output->pause(paused); | 269 pb->output->pause(paused); |
| 295 static void destroy_cb(mowgli_dictionary_elem_t *delem, void *privdata) { | 272 static void destroy_cb(mowgli_dictionary_elem_t *delem, void *privdata) { |
| 296 g_free(delem->data); | 273 g_free(delem->data); |
| 297 } | 274 } |
| 298 | 275 |
| 299 Tuple *demac_probe_for_tuple (gchar *uri, VFSFile *vfd) { | 276 Tuple *demac_probe_for_tuple (gchar *uri, VFSFile *vfd) { |
| 300 #ifdef DEBUG | 277 AUDDBG("** demac: plugin.c: demac_probe_for_tuple()\n"); |
| 301 fprintf(stderr, "** demac: plugin.c: demac_probe_for_tuple()\n"); | |
| 302 #endif | |
| 303 Tuple *tpl = aud_tuple_new_from_filename(uri); | 278 Tuple *tpl = aud_tuple_new_from_filename(uri); |
| 304 gchar codec_string[32]; | 279 gchar codec_string[32]; |
| 305 | 280 |
| 306 if (aud_vfs_is_streaming(vfd)) { | 281 if (aud_vfs_is_streaming(vfd)) { |
| 307 /* This plugin does not support streams yet */ | 282 /* This plugin does not support streams yet */ |
| 323 APEContext *ctx = calloc(sizeof(APEContext), 1); | 298 APEContext *ctx = calloc(sizeof(APEContext), 1); |
| 324 aud_vfs_rewind(vfd); | 299 aud_vfs_rewind(vfd); |
| 325 ape_read_header(ctx, vfd, 1); | 300 ape_read_header(ctx, vfd, 1); |
| 326 aud_tuple_associate_int(tpl, FIELD_LENGTH, NULL, ctx->duration); | 301 aud_tuple_associate_int(tpl, FIELD_LENGTH, NULL, ctx->duration); |
| 327 g_sprintf(codec_string, "Monkey's Audio v%4.2f", (float)ctx->fileversion/1000.0); | 302 g_sprintf(codec_string, "Monkey's Audio v%4.2f", (float)ctx->fileversion/1000.0); |
| 328 #ifdef DEBUG | 303 AUDDBG("** demac: plugin.c: Codec: %s\n", codec_string); |
| 329 fprintf(stderr, "** demac: plugin.c: Codec: %s\n", codec_string); | |
| 330 #endif | |
| 331 aud_tuple_associate_string(tpl, FIELD_CODEC, NULL, codec_string); | 304 aud_tuple_associate_string(tpl, FIELD_CODEC, NULL, codec_string); |
| 332 aud_tuple_associate_string(tpl, FIELD_QUALITY, NULL, "lossless"); | 305 aud_tuple_associate_string(tpl, FIELD_QUALITY, NULL, "lossless"); |
| 333 aud_tuple_associate_string(tpl, FIELD_MIMETYPE, NULL, "audio/x-ape"); | 306 aud_tuple_associate_string(tpl, FIELD_MIMETYPE, NULL, "audio/x-ape"); |
| 334 | 307 |
| 335 ape_read_close(ctx); | 308 ape_read_close(ctx); |
| 339 | 312 |
| 340 return tpl; | 313 return tpl; |
| 341 } | 314 } |
| 342 | 315 |
| 343 Tuple *demac_get_tuple(char *filename) { | 316 Tuple *demac_get_tuple(char *filename) { |
| 344 #ifdef DEBUG | 317 AUDDBG("** demac: plugin.c: demac_get_tuple()\n"); |
| 345 fprintf(stderr, "** demac: plugin.c: demac_get_tuple()\n"); | |
| 346 #endif | |
| 347 VFSFile *vfd; | 318 VFSFile *vfd; |
| 348 | 319 |
| 349 if ((vfd = aud_vfs_fopen(filename, "r")) == NULL) { | 320 if ((vfd = aud_vfs_fopen(filename, "r")) == NULL) { |
| 350 return NULL; | 321 return NULL; |
| 351 } | 322 } |
| 357 | 328 |
| 358 static void demac_mseek (InputPlayback *pb, gulong millisecond) { | 329 static void demac_mseek (InputPlayback *pb, gulong millisecond) { |
| 359 g_mutex_lock(demac_mutex); | 330 g_mutex_lock(demac_mutex); |
| 360 seek_to_msec = millisecond; | 331 seek_to_msec = millisecond; |
| 361 g_mutex_unlock(demac_mutex); | 332 g_mutex_unlock(demac_mutex); |
| 362 #ifdef DEBUG | 333 AUDDBG("** demac: plugin.c: seeking to %u msec\n", millisecond); |
| 363 fprintf(stderr, "** demac: plugin.c: seeking to %u msec\n", millisecond); | |
| 364 #endif | |
| 365 } | 334 } |
| 366 | 335 |
| 367 static void demac_seek (InputPlayback *pb, gint time) { | 336 static void demac_seek (InputPlayback *pb, gint time) { |
| 368 demac_mseek(pb, (unsigned long)time*1000); | 337 demac_mseek(pb, (unsigned long)time*1000); |
| 369 } | 338 } |
