libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/synth/util.hpp
Go to the documentation of this file.
00001 
00011 /*
00012  *  Copyright (C) 2011 Juan Pedro BolĂ­var 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 #ifndef PSYNTH_SYNTH_UTIL_H_
00032 #define PSYNTH_SYNTH_UTIL_H_
00033 
00034 #include <psynth/sound/forwards.hpp>
00035 #include <psynth/sound/algorithm.hpp>
00036 
00037 namespace psynth
00038 {
00039 namespace synth
00040 {
00041 
00045 template <class Range>
00046 std::size_t find_hill (const Range& data, std::size_t start)
00047 {
00048     typedef typename sound::sample_type<Range>::type sample_type; 
00049     const auto zero = sound::sample_traits<sample_type>::zero_value ();
00050     ++start;
00051    
00052     while (start < (size_t) data.size () &&
00053            (data [start-1] != zero ||
00054             data [start] == zero))
00055         ++start;
00056     
00057     return start;
00058 }
00059 
00060 template <class R1, class R2, class R3>
00061 void mix (const R1& src1, const R2& src2, const R3& dst)
00062 {
00063     typedef typename R1::value_type src1_frame;
00064     typedef typename R2::value_type src2_frame;
00065     typedef typename R3::value_type dst_frame;
00066 
00067     // FIXME: Only for homogeneous frames!
00068     typedef std::plus<typename sound::sample_type<dst_frame>::type> mix_op;
00069     
00070     sound::transform_frames (
00071         src1, src2, dst,
00072         [] (const src1_frame& a, const src2_frame& b)
00073         {
00074             dst_frame res;
00075             static_transform (a, b, res, mix_op ());
00076             return res;
00077         });
00078 }
00079 
00080 template <class R1, class R2, class R3, typename Sample>
00081 void mix (const R1& src1, const R2& src2, Sample ampl, const R3& dst)
00082 {
00083     typedef typename R1::value_type src1_frame;
00084     typedef typename R2::value_type src2_frame;
00085     typedef typename R3::value_type dst_frame;
00086     typedef typename sound::sample_type<dst_frame>::type sample_type;
00087     
00088     sound::transform_frames (
00089         src1, src2, dst,
00090         [&] (const src1_frame& a, const src2_frame& b)
00091         {
00092             dst_frame res;
00093             static_transform (
00094                 a, b, res,
00095                 [&] (sample_type a, sample_type b) {
00096                     return a + b * ampl;
00097                 });
00098             return res;
00099         });
00100 }
00101 
00102 template <class R1, class R2, class R3, typename Sample>
00103 void blend (const R1& src1, const R2& src2, Sample stable, const R3& dst)
00104 {
00105     typedef typename R1::value_type src1_frame;
00106     typedef typename R2::value_type src2_frame;
00107     typedef typename R3::value_type dst_frame;
00108 
00109     typedef typename sound::sample_type<src1_frame>::type sample_type; 
00110     typedef sound::sample_multiplier<sample_type> blend_op;
00111     const auto max_value = sound::sample_traits<sample_type>::max_value ();
00112     
00113     sound::transform_frames (
00114         src1, src2, dst,
00115         [&] (const src1_frame& a, const src2_frame& b)
00116         {
00117             dst_frame res;
00118             static_transform (
00119                 a, b, res, [&] (const sample_type a, sample_type b) {
00120                     return // FIXME: sample_multiply ?
00121                         a * b + stable * (max_value - b); 
00122                 });
00123             return res;
00124         });
00125 }
00126 
00127 } /* namespace synth */
00128 } /* namespace psynth */
00129 
00130 #endif /* PSYNTH_SYNTH_UTIL_H_ */
00131