root/branches/new_fx_rack_and_sample_fun/libs/hydrogen/src/sample.cpp @ 666

Revision 666, 9.7 KB (checked in by wolke, 4 years ago)

add panorama edit frontend

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include <hydrogen/sample.h>
24#include <hydrogen/hydrogen.h>
25#include <hydrogen/Preferences.h>
26
27#include "flac_file.h"
28
29#include <sndfile.h>
30#include <iostream>
31#include <fstream>
32#include <algorithm>
33#include <vector>
34
35#include "gui/src/HydrogenApp.h"
36#include "gui/src/SampleEditor/SampleEditor.h"
37
38using namespace std;
39
40namespace H2Core
41{
42
43Sample::Sample( unsigned frames,
44                const QString& filename,
45                float* data_l,
46                float* data_r,
47                bool sample_is_modified,
48                const QString& sample_mode,
49                unsigned start_frame,
50                unsigned loop_frame,
51                int repeats,
52                unsigned end_frame,
53                SampleVeloPan velopan )
54
55                : Object( "Sample" )
56                , __data_l( data_l )
57                , __data_r( data_r )
58                , __sample_rate( 44100 )
59                , __filename( filename )
60                , __n_frames( frames )
61                , __sample_is_modified( sample_is_modified )
62                , __sample_mode( sample_mode )
63                , __start_frame( start_frame )
64                , __loop_frame( loop_frame )
65                , __repeats( repeats )
66                , __end_frame( end_frame )
67                , __velo_pan( velopan )
68{
69                //INFOLOG("INIT " + m_sFilename + ". nFrames: " + toString( nFrames ) );
70}
71
72
73
74Sample::~Sample()
75{
76        delete[] __data_l;
77        delete[] __data_r;
78        //INFOLOG( "DESTROY " + m_sFilename);
79}
80
81
82
83Sample* Sample::load( const QString& filename )
84{
85        // is it a flac file?
86        if ( ( filename.endsWith( "flac") ) || ( filename.endsWith( "FLAC" )) ) {
87                return load_flac( filename );
88        } else {
89                return load_wave( filename );
90        }
91}
92
93
94
95/// load a FLAC file
96Sample* Sample::load_flac( const QString& filename )
97{
98#ifdef FLAC_SUPPORT
99        FLACFile file;
100        return file.load( filename );
101#else
102        _ERRORLOG("[loadFLAC] FLAC support was disabled during compilation");
103        return NULL;
104#endif
105}
106
107
108
109Sample* Sample::load_wave( const QString& filename )
110{
111        // file exists?
112        if ( QFile( filename ).exists() == false ) {
113                _ERRORLOG( QString( "[Sample::load] Load sample: File %1 not found" ).arg( filename ) );
114                return NULL;
115        }
116
117
118        SF_INFO soundInfo;
119        SNDFILE* file = sf_open( filename.toAscii(), SFM_READ, &soundInfo );
120        if ( !file ) {
121                _ERRORLOG( QString( "[Sample::load] Error loading file %1" ).arg( filename ) );
122        }
123
124
125        float *pTmpBuffer = new float[ soundInfo.frames * soundInfo.channels ];
126
127        //int res = sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
128        sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
129        sf_close( file );
130
131        float *data_l = new float[ soundInfo.frames ];
132        float *data_r = new float[ soundInfo.frames ];
133
134
135        if ( soundInfo.channels == 1 ) {        // MONO sample
136                for ( long int i = 0; i < soundInfo.frames; i++ ) {
137                        data_l[i] = pTmpBuffer[i];
138                        data_r[i] = pTmpBuffer[i];
139                }
140        } else if ( soundInfo.channels == 2 ) { // STEREO sample
141                for ( long int i = 0; i < soundInfo.frames; i++ ) {
142                        data_l[i] = pTmpBuffer[i * 2];
143                        data_r[i] = pTmpBuffer[i * 2 + 1];
144                }
145        }
146        delete[] pTmpBuffer;
147
148        Sample *pSample = new Sample( soundInfo.frames, filename );
149        pSample->__data_l = data_l;
150        pSample->__data_r = data_r;
151        pSample->__sample_rate = soundInfo.samplerate;
152//      pSample->reverse_sample( pSample ); // test reverse
153        return pSample;
154}
155
156
157Sample* Sample::load_edit_wave( const QString& filename,
158                                const unsigned startframe,
159                                const unsigned loppframe,
160                                const unsigned endframe,
161                                const int loops,
162                                const QString loopmode)
163{
164
165        Hydrogen *pEngine = Hydrogen::get_instance();
166
167        // file exists?
168        if ( QFile( filename ).exists() == false ) {
169                _ERRORLOG( QString( "[Sample::load] Load sample: File %1 not found" ).arg( filename ) );
170                return NULL;
171        }
172
173
174        SF_INFO soundInfo;
175        SNDFILE* file = sf_open( filename.toAscii(), SFM_READ, &soundInfo );
176        if ( !file ) {
177                _ERRORLOG( QString( "[Sample::load] Error loading file %1" ).arg( filename ) );
178        }
179
180        unsigned onesamplelength =  endframe - startframe;
181        unsigned looplength =  endframe - loppframe;
182        unsigned repeatslength = looplength * loops;
183        unsigned newlength = 0;
184        if (onesamplelength == looplength){     
185                newlength = onesamplelength + onesamplelength * loops ;
186        }else
187        {
188                newlength =onesamplelength + repeatslength;
189        }
190
191        float *pTmpBuffer = new float[ soundInfo.frames * soundInfo.channels ];
192
193        //int res = sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
194        sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
195        sf_close( file );
196
197        float *origdata_l = new float[ soundInfo.frames ];
198        float *origdata_r = new float[ soundInfo.frames ];
199
200
201        if ( soundInfo.channels == 1 ) {        // MONO sample
202                for ( long int i = 0; i < soundInfo.frames; i++ ) {
203                        origdata_l[i] = pTmpBuffer[i];
204                        origdata_r[i] = pTmpBuffer[i];
205                }
206        } else if ( soundInfo.channels == 2 ) { // STEREO sample
207                for ( long int i = 0; i < soundInfo.frames; i++ ) {
208                        origdata_l[i] = pTmpBuffer[i * 2];
209                        origdata_r[i] = pTmpBuffer[i * 2 + 1];
210                }
211        }
212        delete[] pTmpBuffer;
213
214        float *tempdata_l = new float[ newlength ];
215        float *tempdata_r = new float[ newlength ];
216
217        float *looptempdata_l = new float[ looplength ];
218        float *looptempdata_r = new float[ looplength ];
219
220        long int z = loppframe;
221        long int y = startframe;
222
223        for ( unsigned i = 0; i < newlength; i++){ //first vector
224
225                tempdata_l[i] = 0;
226                tempdata_r[i] = 0;
227        }
228
229        for ( unsigned i = 0; i < onesamplelength; i++, y++){ //first vector
230
231                tempdata_l[i] = origdata_l[y];
232                tempdata_r[i] = origdata_r[y];
233        }
234
235        for ( unsigned i = 0; i < looplength; i++, z++){ //loop vector
236
237                looptempdata_l[i] = origdata_l[z];
238                looptempdata_r[i] = origdata_r[z];
239        }
240
241               
242        if ( loopmode == "reverse" ){
243                reverse(looptempdata_l, looptempdata_l + looplength);
244                reverse(looptempdata_r, looptempdata_r + looplength);
245        }
246
247        if ( loopmode == "reverse" && loops > 0 && startframe == loppframe ){
248                reverse( tempdata_l, tempdata_l + onesamplelength );
249                reverse( tempdata_r, tempdata_r + onesamplelength );           
250                }
251
252        if ( loopmode == "pingpong" &&  startframe == loppframe){
253                reverse(looptempdata_l, looptempdata_l + looplength);
254                reverse(looptempdata_r, looptempdata_r + looplength);
255        }
256       
257        for ( int i = 0; i< loops ;i++){
258                       
259                unsigned tempdataend = onesamplelength + ( looplength * i );
260                copy( looptempdata_l, looptempdata_l+looplength ,tempdata_l+tempdataend );
261                copy( looptempdata_r, looptempdata_r+looplength ,tempdata_r+tempdataend );
262                if ( loopmode == "pingpong" && loops > 1){
263                        reverse(looptempdata_l, looptempdata_l + looplength);
264                        reverse(looptempdata_r, looptempdata_r + looplength);
265                }
266
267        }
268
269       
270        if ( loops == 0 && loopmode == "reverse" ){
271                reverse( tempdata_l + loppframe, tempdata_l + newlength);
272                reverse( tempdata_r + loppframe, tempdata_r + newlength);               
273                }
274
275
276
277        //create new sample
278        Sample *pSample = new Sample( newlength, filename );
279
280        //check for volume vector
281        if ( (pEngine->m_volumen.size() > 2 )|| ( pEngine->m_volumen.size() == 2 &&  (pEngine->m_volumen[0].m_hyvalue > 0 || pEngine->m_volumen[1].m_hyvalue > 0 ))){
282
283                //1. write velopan into sample
284                SampleVeloPan::SampleVeloVector velovec;
285                pSample->__velo_pan.m_Samplevolumen.clear();
286                for (int i = 0; i < static_cast<int>(pEngine->m_volumen.size()); i++){         
287                        velovec.m_SampleVeloframe = pEngine->m_volumen[i].m_hxframe;
288                        velovec.m_SampleVelovalue = pEngine->m_volumen[i].m_hyvalue;
289                        pSample->__velo_pan.m_Samplevolumen.push_back( velovec );
290                }
291                //2. compute volume
292                float divider = newlength / 841.0F;
293                for (int i = 1; i  < static_cast<int>(pEngine->m_volumen.size()); i++){
294                       
295                        double y =  (91 - static_cast<int>(pEngine->m_volumen[i - 1].m_hyvalue))/91.0F;
296                        double k = (91 - static_cast<int>(pEngine->m_volumen[i].m_hyvalue))/91.0F;
297
298                        unsigned deltastartframe = pEngine->m_volumen[i - 1].m_hxframe * divider;
299                        unsigned deltaendframe = pEngine->m_volumen[i].m_hxframe * divider;
300
301                        if ( i == static_cast<int>(pEngine->m_volumen.size()) -1) deltaendframe = newlength;
302                        unsigned deltaIdiff = deltaendframe - deltastartframe ;
303                        double subtract = 0.0F;
304
305                        if ( y > k ){
306                                subtract = (y - k) / deltaIdiff;
307                        }else
308                        {
309                                subtract = ( k - y) / deltaIdiff * (-1);
310                        }
311                        //_INFOLOG( QString( "start y %1, end y %2 sub: %3, deltadiff %4" ).arg( y ).arg( k ).arg(subtract).arg(deltaIdiff) );
312                        for ( int z = static_cast<int>(deltastartframe) ; z < static_cast<int>(deltaendframe); z++){                   
313                                tempdata_l[z] = tempdata_l[z] * y;
314                                tempdata_r[z] = tempdata_r[z] * y;
315                                y = y - subtract;
316                        }
317                }
318               
319        }
320
321        //check for pan vector
322        if ( (pEngine->m_pan.size() > 2 )|| ( pEngine->m_pan.size() == 2 &&  (pEngine->m_pan[0].m_hyvalue != 45 || pEngine->m_pan[1].m_hyvalue != 45 ))){
323                //first step write velopan into sample
324                SampleVeloPan::SamplePanVector panvec;
325                pSample->__velo_pan.m_SamplePan.clear();
326                for (int i = 0; i < static_cast<int>(pEngine->m_pan.size()); i++){             
327                        panvec.m_SamplePanframe = pEngine->m_pan[i].m_hxframe;
328                        panvec.m_SamplePanvalue = pEngine->m_pan[i].m_hyvalue;
329                        pSample->__velo_pan.m_SamplePan.push_back( panvec );
330                }
331               
332        }
333
334        pSample->__data_l = tempdata_l;
335        pSample->__data_r = tempdata_r;
336        pSample->__sample_rate = soundInfo.samplerate;
337        pSample->__sample_is_modified = true;
338        pSample->__sample_mode = loopmode;
339        pSample->__start_frame = startframe;
340        pSample->__loop_frame = loppframe;
341        pSample->__end_frame = endframe;
342        pSample->__repeats = loops;
343
344        return pSample;
345
346}
347};
348
Note: See TracBrowser for help on using the browser.