📄 speex_a.c
字号:
ctx->header.nb_channels = ctx->channels; ctx->header.frames_per_packet = ctx->nframes = speex_options.nframes; ctx->state = speex_encoder_init(ctx->mode); /*Set the quality to 8 (15 kbps)*/ speex_encoder_ctl(ctx->state, SPEEX_SET_QUALITY, &speex_options.quality); if(strcmp(fname, "-") == 0) { fd = 1; /* data to stdout */ if(comment == NULL) comment = "(stdout)"; } else { /* Open the audio file */ fd = open(fname, FILE_OUTPUT_MODE); if(fd < 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", fname, strerror(errno)); return -1; } if(comment == NULL) comment = fname; } write_ogg_header(ctx, fd, (char *)comment); speex_encoder_ctl(ctx->state, SPEEX_GET_FRAME_SIZE, &ctx->frame_size); speex_encoder_ctl(ctx->state, SPEEX_SET_COMPLEXITY, &speex_options.complexity); speex_encoder_ctl(ctx->state, SPEEX_SET_SAMPLING_RATE, &dpm.rate); if (speex_options.vbr) { speex_encoder_ctl(ctx->state, SPEEX_SET_VBR, &speex_options.vbr); } else if (speex_options.vad) { speex_encoder_ctl(ctx->state, SPEEX_SET_VAD, &speex_options.vad); } if (speex_options.dtx) speex_encoder_ctl(ctx->state, SPEEX_SET_DTX, &speex_options.dtx); if (speex_options.dtx && !(speex_options.vbr || speex_options.abr || speex_options.vad)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "--speex-dtx is useless without --speex-vad, --speex-vbr or --speex-abr"); } else if ((speex_options.vbr || speex_options.abr) && (speex_options.vad)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "--speex-vad is already implied by --speex-vbr or --speex-abr"); } if (speex_options.abr) { speex_encoder_ctl(ctx->state, SPEEX_SET_ABR, &speex_options.abr); } speex_bits_init(&ctx->bits); ctx->input = (float *)safe_malloc(sizeof(float) * MAX_FRAME_SIZE * ctx->channels); ctx->input_idx = 0; return fd;}/* code from vorbis_a.c */extern char *create_auto_output_name(const char *input_filename, char *ext_str, char *output_dir, int mode);static int auto_speex_output_open(const char *input_filename, const char *title){ char *output_filename;#if !defined ( IA_W32GUI ) && !defined ( IA_W32G_SYN ) output_filename = create_auto_output_name(input_filename, "ogg", NULL, 0);#else output_filename = create_auto_output_name(input_filename, "ogg", w32g_output_dir, w32g_auto_output_mode);#endif if (output_filename == NULL){ ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "unknown output file name"); return -1; } if ((dpm.fd = speex_output_open(output_filename, input_filename)) == -1) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "files open failed %s->%s", output_filename, input_filename); free(output_filename); return -1; } if (dpm.name != NULL) free(dpm.name); dpm.name = output_filename; ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Output: %s", dpm.name); { char *st_string="mono"; if (speex_ctx->channels == 2) st_string = "stereo"; ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Encoding %d Hz audio using %s mode (%s)", speex_ctx->header.rate, speex_ctx->mode->modeName, st_string); } return 0;}static int open_output(void){ int include_enc, exclude_enc; include_enc = exclude_enc = 0; /* only 16 bit is supported */ include_enc |= PE_16BIT|PE_SIGNED; exclude_enc |= PE_BYTESWAP|PE_24BIT; dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);#if !defined (IA_W32GUI) && !defined (IA_W32G_SYN) if (dpm.name == NULL) { dpm.flag |= PF_AUTO_SPLIT_FILE; dpm.name = NULL; } else { dpm.flag &= ~PF_AUTO_SPLIT_FILE; if ((dpm.fd = speex_output_open(dpm.name, NULL)) == -1) return -1; }#else if (w32g_auto_output_mode > 0){ dpm.flag |= PF_AUTO_SPLIT_FILE; dpm.name = NULL; } else { dpm.flag &= ~PF_AUTO_SPLIT_FILE; if ((dpm.fd = speex_output_open(dpm.name, NULL)) == -1) return -1; }#endif return 0;}static int output_data(char *buf, int32 nbytes){ char cbits[MAX_FRAME_BYTES]; Speex_ctx *ctx = speex_ctx; int nbBytes; int16 *s; int i, j; int ret; int nbytes_left; if (dpm.fd < 0) return 0; ctx->in_bytes += nbytes; /* Main encoding loop (one frame per iteration) */ nbytes_left = nbytes; s = (int16 *)buf; while (1) { ctx->ogg_packetid++; /* packing 16 bit -> float sample */ for (i = ctx->input_idx; i < ctx->frame_size * ctx->channels; i++) { /* stream is ended, and buffer is not full. wait next spooling */ if (nbytes_left < 0) { /* canceling ogg packet */ ctx->ogg_packetid--; return 0; } ctx->input[i] = *s++; nbytes_left -= 2; /* -16 bit*/ ctx->input_idx++; } /* buffer is full. encode now. */ ctx->input_idx = 0; if (ctx->channels == 2) speex_encode_stereo(ctx->input, ctx->frame_size, &ctx->bits); /* Encode the frame */ speex_encode(ctx->state, ctx->input, &ctx->bits); if ((ctx->ogg_packetid + 1) % ctx->nframes != 0) continue; speex_bits_insert_terminator(&ctx->bits); /* Copy the bits to an array of char that can be written */ nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES); /* Flush all the bits in the struct so we can encode a new frame */ speex_bits_reset(&ctx->bits); /* ogg packet setup */ ctx->op.packet = (unsigned char *)cbits; ctx->op.bytes = nbBytes; ctx->op.b_o_s = 0; ctx->op.e_o_s = 0; ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size; ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes; ogg_stream_packetin(&ctx->os, &ctx->op); /* Write all new pages (most likely 0 or 1) */ while (ogg_stream_pageout(&ctx->os, &ctx->og)) { ret = oe_write_page(&ctx->og, dpm.fd); if (ret != ctx->og.header_len + ctx->og.body_len) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output stream"); return -1; } else ctx->out_bytes += ret; } } return 0;}static void close_output(void){ int i; char cbits[MAX_FRAME_BYTES]; Speex_ctx *ctx = speex_ctx; int nbBytes; int ret; if (ctx == NULL) return; if (dpm.fd < 0) return; /* Write last frame */ if (speex_ctx != NULL) { if ((ctx->ogg_packetid + 1) % ctx->nframes != 0) { while ((ctx->ogg_packetid + 1) % ctx->nframes != 0) { ctx->ogg_packetid++; speex_bits_pack(&ctx->bits, 15, 5); } nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES); ctx->op.packet = (unsigned char *)cbits; ctx->op.bytes = nbBytes; ctx->op.b_o_s = 0; ctx->op.e_o_s = 1; ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size; ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes; ogg_stream_packetin(&ctx->os, &ctx->op); } for (i = ctx->input_idx; i < ctx->frame_size * ctx->channels; i++) { /* left is zero-cleaned */ ctx->input[i] = 0; } if (ctx->channels == 2) speex_encode_stereo(ctx->input, ctx->frame_size, &ctx->bits); /* Encode the frame */ speex_encode(ctx->state, ctx->input, &ctx->bits); speex_bits_insert_terminator(&ctx->bits); /* Copy the bits to an array of char that can be written */ nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES); /* Flush all the bits in the struct so we can encode a new frame */ speex_bits_reset(&ctx->bits); /* ogg packet setup */ ctx->op.packet = (unsigned char *)cbits; ctx->op.bytes = nbBytes; ctx->op.b_o_s = 0; ctx->op.e_o_s = 1; ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size; ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes; ogg_stream_packetin(&ctx->os, &ctx->op); /* Write all new pages (most likely 0 or 1) */ while (ogg_stream_pageout(&ctx->os, &ctx->og)) { ret = oe_write_page(&ctx->og, dpm.fd); if (ret != ctx->og.header_len + ctx->og.body_len) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output stream"); return; } else ctx->out_bytes += ret; } ogg_stream_clear(&speex_ctx->os); speex_bits_destroy(&speex_ctx->bits); speex_encoder_destroy(speex_ctx->state); close(dpm.fd); dpm.fd = -1; free(speex_ctx->input); ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Wrote %lu/%lu bytes(%g%% compressed)", ctx->out_bytes, ctx->in_bytes, ((double)ctx->out_bytes / (double)ctx->in_bytes)) * 100.; speex_ctx->input = NULL; free(speex_ctx); speex_ctx = NULL; } return;}static int acntl(int request, void *arg){ switch(request) { case PM_REQ_PLAY_START: if(dpm.flag & PF_AUTO_SPLIT_FILE) return auto_speex_output_open(current_file_info->filename,current_file_info->seq_name); break; case PM_REQ_PLAY_END: if(dpm.flag & PF_AUTO_SPLIT_FILE) { close_output(); return 0; } break; case PM_REQ_DISCARD: return 0; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -