diff options
author | jbrjake <[email protected]> | 2007-12-08 18:15:38 +0000 |
---|---|---|
committer | jbrjake <[email protected]> | 2007-12-08 18:15:38 +0000 |
commit | 63ee07ac2348ba5e4e47834656e1941df96814e1 (patch) | |
tree | 69be429c8b23ac79e9e0cfef5b11a3a1e4578a81 | |
parent | f23b40d16b3a9dec9b5d420e402e7c4fb988ae4a (diff) |
Adds extra, user-selectable dynamic range compression to the liba52 interface, making softer sounds louder. Based on code from liba52's A52Decoder, used in Perian's preferences pane. Set with a job->dynamic_range_compression float, with valid values being 1.0 - 4.0.
Controlled from the CLI with --dynamic-range-compression or -D.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1108 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/common.h | 1 | ||||
-rw-r--r-- | libhb/deca52.c | 32 | ||||
-rw-r--r-- | libhb/work.c | 3 | ||||
-rw-r--r-- | test/test.c | 17 |
4 files changed, 50 insertions, 3 deletions
diff --git a/libhb/common.h b/libhb/common.h index 988ea3d55..be174d17e 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -236,6 +236,7 @@ struct hb_job_s int acodec; int abitrate; int arate; + float dynamic_range_compression; /* Subtitle settings: subtitle: index in hb_title_t's subtitles list, starting diff --git a/libhb/deca52.c b/libhb/deca52.c index 94bf8a540..90dd9e738 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -20,6 +20,7 @@ struct hb_work_private_s int rate; int bitrate; float level; + float dynamic_range_compression; int error; int sync; @@ -56,6 +57,30 @@ hb_work_object_t hb_deca52 = static hb_buffer_t * Decode( hb_work_object_t * w ); /*********************************************************************** + * dynrng_call + *********************************************************************** + * Boosts soft audio -- taken from gbooker's work in A52Decoder, comment and all.. + * Two cases + * 1) The user requested a compression of 1 or less, return the typical power rule + * 2) The user requested a compression of more than 1 (decompression): + * If the stream's requested compression is less than 1.0 (loud sound), return the normal compression + * If the stream's requested compression is more than 1.0 (soft sound), use power rule (which will make + * it louder in this case). + * + **********************************************************************/ +static sample_t dynrng_call (sample_t c, void *data) +{ + double *level = (double *)data; + float levelToUse = (float)*level; + if(c > 1.0 || levelToUse <= 1.0) + { + return powf(c, levelToUse); + } + else + return c; +} + +/*********************************************************************** * hb_work_deca52_init *********************************************************************** * Allocate the work object, initialize liba52 @@ -80,6 +105,8 @@ int deca52Init( hb_work_object_t * w, hb_job_t * job ) pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(w->amixdown); pv->level = 32768.0; + pv->dynamic_range_compression = job->dynamic_range_compression; + pv->next_expected_pts = 0; pv->sequence = 0; @@ -201,6 +228,11 @@ static hb_buffer_t * Decode( hb_work_object_t * w ) /* Feed liba52 */ a52_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 ); + if ( pv->dynamic_range_compression ) + { + a52_dynrng( pv->state, dynrng_call, &pv->dynamic_range_compression); + } + /* 6 blocks per frame, 256 samples per block, channelsused channels */ buf = hb_buffer_init( 6 * 256 * pv->out_discrete_channels * sizeof( float ) ); if (pts == -1) diff --git a/libhb/work.c b/libhb/work.c index 19c498f0f..daabf9962 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -324,6 +324,9 @@ static void do_job( hb_job_t * job, int cpu_count ) "faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" : "vorbis" ) ); } + + if ( job->dynamic_range_compression ) + hb_log(" + dynamic range compression: %f", job->dynamic_range_compression); /* if we are doing AC3 passthru, then remove any non-AC3 audios from the job */ /* otherwise, Bad Things will happen */ diff --git a/test/test.c b/test/test.c index 2fb20dbc4..d49d29df7 100644 --- a/test/test.c +++ b/test/test.c @@ -39,6 +39,7 @@ static int h264_13 = 0; static int h264_30 = 0; static char * audios = NULL; static int audio_mixdown = HB_AMIXDOWN_DOLBYPLII; +static float dynamic_range_compression = 0; static int sub = 0; static int width = 0; static int height = 0; @@ -823,7 +824,11 @@ static int HandleEvents( hb_handle_t * h ) { job->acodec = acodec; } - + if ( dynamic_range_compression ) + { + job->dynamic_range_compression = dynamic_range_compression; + } + if( size ) { job->vbitrate = hb_calc_bitrate( job, size ); @@ -1181,7 +1186,9 @@ static void ShowHelp() fprintf( stderr, "/" ); } fprintf( stderr, " kHz)\n" - + " -D, --drc <float> Apply extra dynamic range compression to the audio,\n" + " making soft sounds louder. Range is 1.0 to 4.0\n" + " (too loud), with 1.5 - 2.5 being a useful range.\n" "\n" @@ -1267,6 +1274,7 @@ static int ParseOptions( int argc, char ** argv ) { "markers", optional_argument, NULL, 'm' }, { "audio", required_argument, NULL, 'a' }, { "mixdown", required_argument, NULL, '6' }, + { "drc", required_argument, NULL, 'D' }, { "subtitle", required_argument, NULL, 's' }, { "subtitle-scan", no_argument, NULL, 'U' }, { "subtitle-forced", no_argument, NULL, 'F' }, @@ -1308,7 +1316,7 @@ static int ParseOptions( int argc, char ** argv ) int c; c = getopt_long( argc, argv, - "hvuC:f:4i:Io:t:Lc:ma:6:s:UFN:e:E:2d789gpOP::w:l:n:b:q:S:B:r:R:Qx:TY:X:VZ:z", + "hvuC:f:4i:Io:t:Lc:ma:6:s:UFN:e:E:2dD:789gpOP::w:l:n:b:q:S:B:r:R:Qx:TY:X:VZ:z", long_options, &option_index ); if( c < 0 ) { @@ -1416,6 +1424,9 @@ static int ParseOptions( int argc, char ** argv ) audio_mixdown = HB_AMIXDOWN_6CH; } break; + case 'D': + dynamic_range_compression = atof( optarg ); + break; case 's': sub = atoi( optarg ); break; |