int enclameInit( hb_work_object_t * w, hb_job_t * job ) { hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); hb_audio_t * audio = w->audio; w->private_data = pv; pv->job = job; hb_log( "enclame: opening libmp3lame" ); pv->lame = lame_init(); // use ABR lame_set_scale( pv->lame, 32768.0 ); if( audio->config.out.compression_level >= 0 ) { lame_set_quality( pv->lame, audio->config.out.compression_level ); } if( audio->config.out.bitrate > 0 ) { lame_set_VBR( pv->lame, vbr_abr ); lame_set_VBR_mean_bitrate_kbps( pv->lame, audio->config.out.bitrate ); } else if( audio->config.out.quality >= 0 ) { lame_set_brate( pv->lame, 0 ); lame_set_VBR( pv->lame, vbr_default ); lame_set_VBR_quality( pv->lame, audio->config.out.quality ); } lame_set_in_samplerate( pv->lame, audio->config.out.samplerate ); lame_set_out_samplerate( pv->lame, audio->config.out.samplerate ); pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown ); // Lame's default encoding mode is JOINT_STEREO. This subtracts signal // that is "common" to left and right (within some threshold) and encodes // it separately. This improves quality at low bitrates, but hurts // imaging (channel separation) at higher bitrates. So if the bitrate // is suffeciently high, use regular STEREO mode. if ( pv->out_discrete_channels == 1 ) { lame_set_mode( pv->lame, MONO ); lame_set_num_channels( pv->lame, 1 ); } else if ( audio->config.out.bitrate >= 128 ) { lame_set_mode( pv->lame, STEREO ); } lame_init_params( pv->lame ); pv->input_samples = 1152 * pv->out_discrete_channels; pv->output_bytes = LAME_MAXMP3BUFFER; pv->buf = malloc( pv->input_samples * sizeof( float ) ); audio->config.out.samples_per_frame = 1152; pv->list = hb_list_init(); pv->pts = -1; return 0; }
int mp3_encode(int fd_in, int fd_out) { lame_global_flags *gfp; uint32_t i, j, k, count; int16_t *b0 = 0, *b1 = 0; unsigned char *c; int ret; /* calculate data size*/ k = (uint32_t) lseek(fd_in, 0, SEEK_CUR); i = (uint32_t) lseek(fd_in, 0, SEEK_END); lseek(fd_in, k, SEEK_SET); i -= k; k = 0; gfp = lame_init(); lame_set_errorf(gfp,lame_error_handler); lame_set_debugf(gfp,lame_error_handler); lame_set_msgf(gfp,lame_error_handler); lame_set_num_channels(gfp,2); lame_set_in_samplerate(gfp,8000); #if 0 lame_set_brate(gfp,64); /* compress 1:4 */ lame_set_mode(gfp,0); /* mode = stereo */ lame_set_quality(gfp,2); /* 2=high 5 = medium 7=low */ #else lame_set_quality(gfp,5); /* 2=high 5 = medium 7=low */ lame_set_mode(gfp,3); /* mode = mono */ if(lame_get_VBR(gfp) == vbr_off) lame_set_VBR(gfp, vbr_default); lame_set_VBR_quality(gfp, 7.0); lame_set_findReplayGain(gfp, 0); lame_set_bWriteVbrTag(gfp, 1); lame_set_out_samplerate(gfp,11025); /* lame_set_num_samples(gfp,i/2); */ #endif if(lame_init_params(gfp) < 0) { log_err("encode: failed to init lame"); return 0; } #define CHSZ (512*1024) #define OCHSZ (5*(CHSZ/8)+7200) b0 = (int16_t *) malloc(OCHSZ); b1 = (int16_t *) malloc(CHSZ); if(!b0 || !b1) { log_err("encode: out of memory"); if(b0) free(b0); if(b1) free(b1); return 0; } do { ret = 0; j = 0; count = 0; for(c = (unsigned char*) b1; count < CHSZ; c += ret) { j = (k + RSZ > i) ? i - k : RSZ; ret = read(fd_in,c,j); if(ret < 0) break; k += ret; count += ret; if(k == i) break; } if(ret < 0) break; if(count) { ret = lame_encode_buffer(gfp,b1,b1,count/2,(unsigned char *)b0,OCHSZ); if(ret < 0) break; c = (unsigned char *) b0; count = ret; for(j = 0; j < count; j += RSZ, c += ret) { ret = (j + RSZ > count) ? count - j : RSZ; write(fd_out,c,ret); } } } while(k < i); k = (uint32_t) lame_encode_flush(gfp,(unsigned char *)b0,OCHSZ); if(k) write(fd_out,b0,k); k = lame_get_lametag_frame(gfp,(unsigned char *)b0,OCHSZ); if(k > 0) write(fd_out,b0,k); lame_close(gfp); free(b0); free(b1); return 1; }
void lame_encoder_impl_internal::set_vbr_quality(float _Quality) { int lameRet = lame_set_VBR_quality(m_Lame.get(), _Quality); DT_LAME_CHECK_ERR(lameRet); }