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

Revision 625, 7.3 KB (checked in by wolke, 5 years ago)

samples play reverse and pingpong

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
25#include <hydrogen/Preferences.h>
26#include "flac_file.h"
27#include <sndfile.h>
28#include <iostream>
29#include <fstream>
30#include <algorithm>
31#include <vector>
32
33#include "gui/src/HydrogenApp.h"
34#include "gui/src/SampleEditor/SampleEditor.h"
35
36using namespace std;
37
38namespace H2Core
39{
40
41Sample::Sample( unsigned frames,
42                const QString& filename,
43                float* data_l,
44                float* data_r,
45                bool sample_is_modified,
46                const QString& sample_mode,
47                unsigned start_frame,
48                unsigned loop_frame,
49                int repeats,
50                unsigned end_frame,
51                unsigned fade_out_startframe,
52                int fade_out_type  )
53
54                : Object( "Sample" )
55                , __data_l( data_l )
56                , __data_r( data_r )
57                , __sample_rate( 44100 )
58                , __filename( filename )
59                , __n_frames( frames )
60                , __sample_is_modified( sample_is_modified )
61                , __sample_mode( sample_mode )
62                , __start_frame( start_frame )
63                , __loop_frame( loop_frame )
64                , __repeats( repeats )
65                , __end_frame( end_frame )
66                , __fade_out_startframe( fade_out_startframe )
67                , __fade_out_type( fade_out_type )
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        _INFOLOG( QString( "mode: " + loopmode) );
165        _INFOLOG( QString( "loops: " ).arg( loops ) );
166        // file exists?
167        if ( QFile( filename ).exists() == false ) {
168                _ERRORLOG( QString( "[Sample::load] Load sample: File %1 not found" ).arg( filename ) );
169                return NULL;
170        }
171
172
173        SF_INFO soundInfo;
174        SNDFILE* file = sf_open( filename.toAscii(), SFM_READ, &soundInfo );
175        if ( !file ) {
176                _ERRORLOG( QString( "[Sample::load] Error loading file %1" ).arg( filename ) );
177        }
178
179        unsigned onesamplelength =  endframe - startframe;
180        unsigned looplength =  endframe - loppframe;
181        unsigned repeatslength = looplength * loops;
182        unsigned newlength = 0;
183        if (onesamplelength == looplength){     
184                newlength = onesamplelength + onesamplelength * loops ;
185        }else
186        {
187                newlength =onesamplelength + repeatslength;
188        }
189
190        float *pTmpBuffer = new float[ soundInfo.frames * soundInfo.channels ];
191
192        //int res = sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
193        sf_read_float( file, pTmpBuffer, soundInfo.frames * soundInfo.channels );
194        sf_close( file );
195
196        float *origdata_l = new float[ soundInfo.frames ];
197        float *origdata_r = new float[ soundInfo.frames ];
198
199
200        if ( soundInfo.channels == 1 ) {        // MONO sample
201                for ( long int i = 0; i < soundInfo.frames; i++ ) {
202                        origdata_l[i] = pTmpBuffer[i];
203                        origdata_r[i] = pTmpBuffer[i];
204                }
205        } else if ( soundInfo.channels == 2 ) { // STEREO sample
206                for ( long int i = 0; i < soundInfo.frames; i++ ) {
207                        origdata_l[i] = pTmpBuffer[i * 2];
208                        origdata_r[i] = pTmpBuffer[i * 2 + 1];
209                }
210        }
211        delete[] pTmpBuffer;
212
213        float *tempdata_l = new float[ newlength ];
214        float *tempdata_r = new float[ newlength ];
215
216        float *looptempdata_l = new float[ looplength ];
217        float *looptempdata_r = new float[ looplength ];
218
219        long int z = loppframe;
220        long int y = startframe;
221
222        for ( unsigned i = 0; i < newlength; i++){ //first vector
223
224                tempdata_l[i] = 0;
225                tempdata_r[i] = 0;
226        }
227
228        for ( unsigned i = 0; i < onesamplelength; i++, y++){ //first vector
229
230                tempdata_l[i] = origdata_l[y];
231                tempdata_r[i] = origdata_r[y];
232        }
233
234        for ( unsigned i = 0; i < looplength; i++, z++){ //loop vector
235
236                looptempdata_l[i] = origdata_l[z];
237                looptempdata_r[i] = origdata_r[z];
238        }
239
240               
241        if ( loopmode == "reverse" ){
242                reverse(looptempdata_l, looptempdata_l + looplength);
243                reverse(looptempdata_r, looptempdata_r + looplength);
244        }
245
246        if ( loopmode == "reverse" && loops > 0 && startframe == loppframe ){
247                reverse( tempdata_l, tempdata_l + onesamplelength );
248                reverse( tempdata_r, tempdata_r + onesamplelength );           
249                }
250
251       
252        for ( int i = 0; i< loops ;i++){
253
254                unsigned tempdataend = onesamplelength + ( looplength * i );
255                copy( looptempdata_l, looptempdata_l+looplength ,tempdata_l+tempdataend );
256                copy( looptempdata_r, looptempdata_r+looplength ,tempdata_r+tempdataend );
257                if ( loopmode == "pingpong" ){
258                        reverse(looptempdata_l, looptempdata_l + looplength);
259                        reverse(looptempdata_r, looptempdata_r + looplength);
260                }
261
262        }
263
264       
265        if ( loops == 0 && loopmode == "reverse" ){
266                reverse( tempdata_l + loppframe, tempdata_l + newlength);
267                reverse( tempdata_r + loppframe, tempdata_r + newlength);               
268                }
269
270
271        Sample *pSample = new Sample( newlength, filename );
272        pSample->__data_l = tempdata_l;
273        pSample->__data_r = tempdata_r;
274        pSample->__sample_rate = soundInfo.samplerate;
275//      pSample->reverse_sample( pSample ); // test reverse
276        return pSample;
277
278
279}
280};
281
Note: See TracBrowser for help on using the browser.