[Jahshaka-cvs] SF.net SVN: openlibraries:[1466] trunk/src/openmedialib/ml/utilities.cpp
Status: Beta
Brought to you by:
jahshaka
From: <tim...@us...> - 2009-04-08 11:32:54
|
Revision: 1466 http://openlibraries.svn.sourceforge.net/openlibraries/?rev=1466&view=rev Author: timdewhirst Date: 2009-04-08 11:32:47 +0000 (Wed, 08 Apr 2009) Log Message: ----------- OML * add 16 & 8 channel audio conversion Modified Paths: -------------- trunk/src/openmedialib/ml/utilities.cpp Modified: trunk/src/openmedialib/ml/utilities.cpp =================================================================== --- trunk/src/openmedialib/ml/utilities.cpp 2009-04-02 09:42:39 UTC (rev 1465) +++ trunk/src/openmedialib/ml/utilities.cpp 2009-04-08 11:32:47 UTC (rev 1466) @@ -1,4 +1,4 @@ - +/* -*- mode: C++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- */ // ml - A media library representation. // Copyright (C) 2005-2006 Editopia Inc. @@ -17,6 +17,7 @@ #include <openmedialib/ml/openmedialib_plugin.hpp> #include <openpluginlib/pl/openpluginlib.hpp> #include <openpluginlib/pl/utf8_utils.hpp> +#include <openpluginlib/pl/log.hpp> #include <deque> namespace pl = olib::openpluginlib; @@ -31,7 +32,7 @@ // Define min and max values for shorts // Note: Syntax used to avoid clash with min & max macro definitions - // see http://www.boost.org/more/lib_guide.htm + // see http://www.boost.org/more/lib_guide.htm const short min_short = (std::numeric_limits<short>::min)(); const short max_short = (std::numeric_limits<short>::max)(); @@ -59,8 +60,8 @@ int calculate_cycle_size(double frames_per_second, int samplefreq, double samples_per_frame, int &deficit) { - int cycle_size = int(floor(frames_per_second + 0.5)); - double extra_samples = (int(floor(samples_per_frame + 0.5)) * int(floor(frames_per_second + 0.5))) - (samplefreq * int(floor(frames_per_second + 0.5)) / frames_per_second); + int cycle_size = int(floor(frames_per_second + 0.5)); + double extra_samples = (int(floor(samples_per_frame + 0.5)) * int(floor(frames_per_second + 0.5))) - (samplefreq * int(floor(frames_per_second + 0.5)) / frames_per_second); while(int(extra_samples*1000) % 1000 != 0 && cycle_size <= 3000) { @@ -196,6 +197,8 @@ case 3: case 4: case 6: + case 8: + case 16: return true; } break; @@ -207,19 +210,35 @@ case 4: case 5: case 6: + case 8: + case 16: return true; } break; case 4: switch(channels_in) { - //case 1: + case 1: case 2: - //case 3: + case 3: case 6: + case 8: + case 16: return true; } break; + case 8: + switch(channels_in) + { + case 1: + case 2: + case 3: + case 4: + case 6: + case 16: + return true; + } + break; } return false; @@ -234,7 +253,7 @@ { case 2: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_RIGHT = 1; sum[0] = ( float( input[ CHANNEL_IDX_LEFT ] ) + float( input[ CHANNEL_IDX_RIGHT ] ) ); @@ -242,18 +261,18 @@ break; case 3: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; - sum[0] = ( float(input[ CHANNEL_IDX_LEFT ]) - + float(input[ CHANNEL_IDX_RIGHT ]) ) - + float(input[ CHANNEL_IDX_CENTRE ]); + sum[0] = ( float(input[ CHANNEL_IDX_LEFT ]) + + float(input[ CHANNEL_IDX_RIGHT ]) ) + + float(input[ CHANNEL_IDX_CENTRE ]); } break; case 4: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_RIGHT = 1; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 2; const unsigned char CHANNEL_IDX_RIGHT_SURROUND = 3; @@ -266,7 +285,7 @@ break; case 6: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 3; @@ -281,6 +300,34 @@ + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ]); } break; + case 8: + { + const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_RIGHT = 1; + const unsigned char CHANNEL_IDX_CENTER = 2; + const unsigned char CHANNEL_IDX_LOW_FREQ_EFFECTS = 3; + const unsigned char CHANNEL_IDX_LEFT_BACK = 4; + const unsigned char CHANNEL_IDX_RIGHT_BACK = 5; + const unsigned char CHANNEL_IDX_LEFT_SIDE = 6; + const unsigned char CHANNEL_IDX_RIGHT_SIDE = 7; + + sum[0] = ( float(input[ CHANNEL_IDX_LEFT ] ) + + float(input[ CHANNEL_IDX_RIGHT ] ) + + float(input[ CHANNEL_IDX_CENTER ] ) + + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ] ) + + float(input[ CHANNEL_IDX_LEFT_BACK ] ) + + float(input[ CHANNEL_IDX_RIGHT_BACK ] ) + + float(input[ CHANNEL_IDX_LEFT_SIDE ] ) + + float(input[ CHANNEL_IDX_RIGHT_SIDE ] ) ); + } + break; + case 16: + { + sum[0] = 0; + for ( unsigned int i=0; i<16; ++i ) + sum[0] += float(input[ i ]); + } + break; } break; case 2: @@ -292,7 +339,7 @@ break; case 3: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; @@ -305,38 +352,38 @@ break; case 4: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_RIGHT = 1; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 2; const unsigned char CHANNEL_IDX_RIGHT_SURROUND = 3; sum[0] = float(input[ CHANNEL_IDX_LEFT ]) - + float(input[ CHANNEL_IDX_LEFT_SURROUND ]); + + float(input[ CHANNEL_IDX_LEFT_SURROUND ]); sum[1] = float(input[ CHANNEL_IDX_RIGHT ]) - + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]); + + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]); } break; case 5: { - const unsigned char CHANNEL_IDX_LEFT = 0; - const unsigned char CHANNEL_IDX_CENTRE = 1; + const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 3; const unsigned char CHANNEL_IDX_RIGHT_SURROUND = 4; sum[0] = float(input[ CHANNEL_IDX_LEFT ]) - + float(input[ CHANNEL_IDX_LEFT_SURROUND ]) + + float(input[ CHANNEL_IDX_LEFT_SURROUND ]) + float(input[ CHANNEL_IDX_CENTRE ]); sum[1] = float(input[ CHANNEL_IDX_RIGHT ]) - + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]) + + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]) + float(input[ CHANNEL_IDX_CENTRE ]); } break; case 6: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 3; @@ -344,16 +391,51 @@ const unsigned char CHANNEL_IDX_LOW_FREQ_EFFECTS = 5; sum[0] = float(input[ CHANNEL_IDX_LEFT ]) - + float(input[ CHANNEL_IDX_LEFT_SURROUND ]) + + float(input[ CHANNEL_IDX_LEFT_SURROUND ]) + float(input[ CHANNEL_IDX_CENTRE ]) + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ]); sum[1] = float(input[ CHANNEL_IDX_RIGHT ]) - + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]) + + float(input[ CHANNEL_IDX_RIGHT_SURROUND ]) + float(input[ CHANNEL_IDX_CENTRE ]) + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ]); } break; + case 8: + { + const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_RIGHT = 1; + const unsigned char CHANNEL_IDX_CENTER = 2; + const unsigned char CHANNEL_IDX_LOW_FREQ_EFFECTS = 3; + const unsigned char CHANNEL_IDX_LEFT_BACK = 4; + const unsigned char CHANNEL_IDX_RIGHT_BACK = 5; + const unsigned char CHANNEL_IDX_LEFT_SIDE = 6; + const unsigned char CHANNEL_IDX_RIGHT_SIDE = 7; + + sum[0] = ( float(input[ CHANNEL_IDX_LEFT ] ) + + float(input[ CHANNEL_IDX_CENTER ] ) + + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ] ) + + float(input[ CHANNEL_IDX_LEFT_BACK ] ) + + float(input[ CHANNEL_IDX_LEFT_SIDE ] ) ); + sum[1] = ( float(input[ CHANNEL_IDX_RIGHT ] ) + + float(input[ CHANNEL_IDX_CENTER ] ) + + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ] ) + + float(input[ CHANNEL_IDX_RIGHT_BACK ] ) + + float(input[ CHANNEL_IDX_RIGHT_SIDE ] ) ); + } + break; + case 16: + { + sum[0] = 0; + sum[1] = 0; + for ( unsigned int i=0; i<16; i+=2 ) + { + sum[0] += float(input[ i ]); + sum[1] += float(input[ i+1 ]); + } + } + break; + } break; case 4: @@ -367,7 +449,7 @@ break; case 2: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_RIGHT = 1; sum[0] = float(input[ CHANNEL_IDX_LEFT ]); @@ -378,7 +460,7 @@ break; case 3: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; @@ -393,7 +475,7 @@ break; case 6: { - const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_LEFT = 0; const unsigned char CHANNEL_IDX_CENTRE = 1; const unsigned char CHANNEL_IDX_RIGHT = 2; const unsigned char CHANNEL_IDX_LEFT_SURROUND = 3; @@ -401,11 +483,11 @@ const unsigned char CHANNEL_IDX_LOW_FREQ_EFFECTS = 5; sum[0] = float(input[ CHANNEL_IDX_LEFT ]) - + float(input[ CHANNEL_IDX_CENTRE ]) + + float(input[ CHANNEL_IDX_CENTRE ]) + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ]); sum[1] = float(input[ CHANNEL_IDX_RIGHT ]) - + float(input[ CHANNEL_IDX_CENTRE ]) + + float(input[ CHANNEL_IDX_CENTRE ]) + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ]); sum[2] = float(input[ CHANNEL_IDX_LEFT_SURROUND ]); @@ -413,6 +495,45 @@ } break; + case 8: + { + const unsigned char CHANNEL_IDX_LEFT = 0; + const unsigned char CHANNEL_IDX_RIGHT = 1; + const unsigned char CHANNEL_IDX_CENTER = 2; + const unsigned char CHANNEL_IDX_LOW_FREQ_EFFECTS = 3; + const unsigned char CHANNEL_IDX_LEFT_BACK = 4; + const unsigned char CHANNEL_IDX_RIGHT_BACK = 5; + const unsigned char CHANNEL_IDX_LEFT_SIDE = 6; + const unsigned char CHANNEL_IDX_RIGHT_SIDE = 7; + + sum[0] = ( float(input[ CHANNEL_IDX_LEFT ] ) + + float(input[ CHANNEL_IDX_CENTER ] ) + + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ] ) ); + sum[1] = ( float(input[ CHANNEL_IDX_RIGHT ] ) + + float(input[ CHANNEL_IDX_CENTER ] ) + + float(input[ CHANNEL_IDX_LOW_FREQ_EFFECTS ] ) ); + sum[2] = ( float(input[ CHANNEL_IDX_LEFT_BACK ] ) + + float(input[ CHANNEL_IDX_LEFT_SIDE ] ) ); + sum[3] = ( float(input[ CHANNEL_IDX_RIGHT_BACK ] ) + + float(input[ CHANNEL_IDX_RIGHT_SIDE ] ) ); + } + break; + case 16: + { + sum[0] = 0; + sum[1] = 0; + sum[2] = 0; + sum[3] = 0; + for ( unsigned int i=0; i<16; i+=4 ) + { + sum[0] += float(input[ i ]); + sum[1] += float(input[ i+1 ]); + sum[2] += float(input[ i+2 ]); + sum[3] += float(input[ i+3 ]); + } + } + break; + } break; } @@ -459,7 +580,7 @@ { openmedialib_plugin_ptr plug = get_plug( resource, L"input" ); if ( plug == 0 ) - std::cerr << "create_input: failed to find a plugin for: " << pl::to_string( resource ) << "\n"; + std::cerr << "create_input: failed to find a plugin for: " << pl::to_string( resource ) << "\n"; return plug == 0 ? input_type_ptr( ) : plug->input( resource ); } @@ -484,7 +605,7 @@ store_type_ptr result = store_type_ptr( ); openmedialib_plugin_ptr plug = get_plug( resource, L"output" ); if ( plug == 0 ) - std::cerr << "create_store: failed to find a plugin for: " << pl::to_string( resource ) << "\n"; + std::cerr << "create_store: failed to find a plugin for: " << pl::to_string( resource ) << "\n"; return plug == 0 ? result : plug->store( resource, frame ); } @@ -534,7 +655,7 @@ double offset = 0.0, delta_offset = 0.0; - int offset_rounded = 0; + int offset_rounded = 0; short sample_a = 0, sample_b = 0; @@ -662,7 +783,7 @@ || (b->af().compare(AUDIO_FORMAT_PCM16) != 0) ) return audio_type_ptr(); - const audio_type::size_type samples_out = a->samples(); // a & b are the same. + const audio_type::size_type samples_out = a->samples(); // a & b are the same. const audio_type::size_type channels_out = a->channels(); audio_type_ptr mix = audio_type_ptr(new audio_type(audio<unsigned char, pcm16>(a->frequency(), channels_out, samples_out))); @@ -707,47 +828,56 @@ return mix; } -ML_DECLSPEC audio_type_ptr audio_channel_convert(const audio_type_ptr& input_audio, int channels) +ML_DECLSPEC audio_type_ptr audio_channel_convert( const audio_type_ptr& input_audio, + int channels_out ) { // Reject if given dodgy input if(input_audio == audio_type_ptr()) return audio_type_ptr(); // Return input if already in desired form - if(input_audio->channels() == channels) + if(input_audio->channels() == channels_out) return input_audio; // Reject if convertion isn't supported - if(!is_channel_convertion_supported(input_audio->channels(), channels)) + if(!is_channel_convertion_supported(input_audio->channels(), channels_out)) + { + DEBUG_LOG << "channel conversion unsupported: " + << "input: " << input_audio->channels() << ", " + << "output: " << channels_out; return audio_type_ptr(); + } // Reject if audio format isn't 16-bit PCM if(input_audio->af().compare(AUDIO_FORMAT_PCM16) != 0) + { + WARNING_LOG << "audio must be 16bit"; return audio_type_ptr(); + } // Create audio object for output const audio_type::size_type samples = input_audio->samples(); - audio_type_ptr output_audio = audio_type_ptr(new audio_type(audio<unsigned char, pcm16>(input_audio->frequency(), channels, samples))); + audio_type_ptr output_audio = audio_type_ptr(new audio_type(audio<unsigned char, pcm16>(input_audio->frequency(), channels_out, samples))); // upfront filter calcs - const double cutoff_to_fs_ratio = 0.5; - const double exponent = exp(-2.0 * M_PI * cutoff_to_fs_ratio); - const double one_minus_exponent = 1 - exponent; + const double cutoff_to_fs_ratio = 0.5; + const double exponent = exp(-2.0 * M_PI * cutoff_to_fs_ratio); + const double one_minus_exponent = 1 - exponent; short *output = (short*)output_audio->data(); - short *input = (short*)input_audio->data(); + short *input = (short*)input_audio->data(); int channels_in = input_audio->channels( ); - std::vector< float > sum( channels ); - std::vector< float > clipped( channels ); + std::vector< float > sum( channels_out ); + std::vector< float > clipped( channels_out ); for(audio_type::size_type sample_idx = 0; sample_idx < samples; ++sample_idx) { // Add appropriate channels together with appropriate weightings requested channels - mix_sample( input, channels_in, channels, sum ); + mix_sample( input, channels_in, channels_out, sum ); input += channels_in; - for(int ch = 0; ch < channels; ++ch) + for(int ch = 0; ch < channels_out; ++ch) { // clip channels appropriately if(sum[ch] < min_short) @@ -761,9 +891,9 @@ if(sample_idx == 0) *output = short( one_minus_exponent * clipped[ch] ); else - *output = short( one_minus_exponent * clipped[ch] + exponent * ( *( output - channels ) ) ); + *output = short( one_minus_exponent * clipped[ch] + exponent * ( *( output - channels_out ) ) ); - output ++; + ++output; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |