libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/channel_convert.hpp
Go to the documentation of this file.
00001 
00011 /*
00012  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00013  *
00014  *  This file is part of Psychosynth.
00015  *   
00016  *  Psychosynth is free software: you can redistribute it and/or modify
00017  *  it under the terms of the GNU General Public License as published by
00018  *  the Free Software Foundation, either version 3 of the License, or
00019  *  (at your option) any later version.
00020  *
00021  *  Psychosynth is distributed in the hope that it will be useful,
00022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *  GNU General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU General Public License
00027  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028  *
00029  */
00030 
00031 /*
00032  *  Copyright 2005-2007 Adobe Systems Incorporated
00033  * 
00034  *  Use, modification and distribution are subject to the Boost
00035  *  Software License, Version 1.0. (See accompanying file
00036  *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
00037  */
00038 
00039 #ifndef PSYNTH_SOUND_CHANNEL_CONVERT_HPP
00040 #define PSYNTH_SOUND_CHANNEL_CONVERT_HPP
00041 
00042 #include <functional>
00043 
00044 #include <psynth/base/compat.hpp>
00045 
00046 #include <psynth/sound/sample_algorithm.hpp>
00047 #include <psynth/sound/frame.hpp>
00048 #include <psynth/sound/metafunctions.hpp>
00049 #include <psynth/sound/util.hpp>
00050 #include <psynth/sound/channel_base_algorithm.hpp>
00051 
00052 #include <psynth/sound/mono.hpp>
00053 #include <psynth/sound/stereo.hpp>
00054 #include <psynth/sound/quad.hpp>
00055 #include <psynth/sound/surround.hpp>
00056 
00057 namespace psynth
00058 {
00059 namespace sound
00060 {
00061 
00062 // Forward-declare
00063 template <typename P>
00064 struct sample_type;
00065 
00066 /*
00067  *
00068  *                 CHANNEL SPACE CONVERSION
00069  *
00070  *
00071  */
00072 
00078 template <typename C1, typename C2>
00079 struct default_channel_converter_impl {};
00080 
00086 template <typename C>
00087 struct default_channel_converter_impl<C, C>
00088 {
00089     template <typename P1, typename P2>
00090     void operator () (const P1& src, P2& dst) const
00091     {
00092         static_for_each (src, dst, default_sample_converter());
00093     }
00094 };
00095 
00096 
00101 template <>
00102 struct default_channel_converter_impl<mono_space, stereo_space>
00103 {
00104     template <typename P1, typename P2>
00105     void operator () (const P1& src, P2& dst) const
00106     {
00107         get_channel (dst, left_channel ())  =
00108             sample_convert<typename channel_element_type<P2,left_channel>::type>(
00109                 get_channel (src, mono_channel ()));
00110         get_channel (dst, right_channel ())  =
00111             sample_convert<typename channel_element_type<P2,right_channel>::type>(
00112                 get_channel (src, mono_channel ()));
00113     }
00114 };
00115 
00120 template <>
00121 struct default_channel_converter_impl<stereo_space, mono_space>
00122 {
00123     template <typename P1, typename P2>
00124     void operator() (const P1& src, P2& dst) const
00125     {
00126         get_channel (dst, mono_channel ()) = 
00127             sample_convert<typename channel_element_type<P2, mono_channel>::type>(
00128                 get_channel (src, left_channel ()) / 2 +
00129                 get_channel (src, right_channel ()) / 2
00130             );
00131     }
00132 };
00133 
00143 struct default_channel_converter
00144 {
00145     template <typename SrcP, typename DstP>
00146     void operator () (const SrcP& src,DstP& dst) const
00147     { 
00148         typedef typename channel_space_type<SrcP>::type SrcChannelSpace;
00149         typedef typename channel_space_type<DstP>::type DstChannelSpace;
00150         default_channel_converter_impl<SrcChannelSpace, DstChannelSpace>()(
00151             src, dst);
00152     }
00153 };
00154 
00163 template <typename SrcP, typename DstP>
00164 inline void channel_convert (const SrcP& src, DstP& dst)
00165 {
00166     default_channel_converter()(src,dst);
00167 }
00168 
00169 template <typename SrcP, typename DstP>
00170 inline DstP channel_convert (const SrcP& src)
00171 {
00172     DstP res;
00173     default_channel_converter()(src,res);
00174     return res;
00175 }
00176 
00177 } /* namespace sound */
00178 } /* namespace psynth */
00179 
00180 #endif /* PSYNTH_SOUND_CHANNEL_CONVERT */