~ubuntu-branches/ubuntu/hardy/lmms/hardy

« back to all changes in this revision

Viewing changes to src/lib/sample_buffer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ragwitz
  • Date: 2005-12-22 16:22:50 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051222162250-key3p7x0212jy6dn
Tags: 0.1.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * sample_buffer.cpp - container-class sampleBuffer
3
3
 *
4
 
 * Linux MultiMedia Studio
5
 
 * Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
 
4
 * Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
 
5
 * 
 
6
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
6
7
 *
7
8
 * This program is free software; you can redistribute it and/or
8
9
 * modify it under the terms of the GNU General Public
36
37
#include <QFileDialog>
37
38
#include <QFileInfo>
38
39
#include <QFile>
 
40
#include <QBuffer>
39
41
 
40
42
#else
41
43
 
45
47
#include <qfiledialog.h>
46
48
#include <qfileinfo.h>
47
49
#include <qfile.h>
 
50
#include <qbuffer.h>
48
51
 
49
52
#if QT_VERSION < 0x030100
50
53
#include <qregexp.h>
67
70
#include <vorbis/vorbisfile.h>
68
71
#endif
69
72
 
 
73
#ifdef HAVE_FLAC_STREAM_ENCODER_H
 
74
#include <FLAC/stream_encoder.h>
 
75
#endif
 
76
 
 
77
#ifdef HAVE_FLAC_STREAM_DECODER_H
 
78
#include <FLAC/stream_decoder.h>
 
79
#endif
 
80
 
70
81
 
71
82
#include "sample_buffer.h"
72
83
#include "interpolation.h"
77
88
#include "debug.h"
78
89
 
79
90
 
80
 
 
81
 
sampleBuffer::sampleBuffer( const QString & _audio_file ) :
 
91
#ifndef QT4
 
92
 
 
93
#define write writeBlock
 
94
#define read readBlock
 
95
#define seek at 
 
96
#define pos at
 
97
 
 
98
#endif
 
99
 
 
100
 
 
101
 
 
102
sampleBuffer::sampleBuffer( const QString & _audio_file,
 
103
                                                        bool _is_base64_data ) :
82
104
        QObject(),
83
 
        m_audioFile( _audio_file ),
 
105
        m_audioFile( ( _is_base64_data == TRUE ) ? "" : _audio_file ),
84
106
        m_origData( NULL ),
85
107
        m_origFrames( 0 ),
86
108
        m_data( NULL ),
98
120
#ifdef HAVE_SAMPLERATE_H
99
121
        initResampling();
100
122
#endif
 
123
        if( _is_base64_data == TRUE )
 
124
        {
 
125
                loadFromBase64( _audio_file );
 
126
        }
101
127
        update();
102
128
}
103
129
 
118
144
        m_dataMutex()
119
145
{
120
146
        m_origData = new sampleFrame[_frames];
121
 
        memcpy( m_origData, _data, _frames*BYTES_PER_FRAME );
 
147
        memcpy( m_origData, _data, _frames * BYTES_PER_FRAME );
122
148
        m_origFrames = _frames;
123
149
#ifdef SDL_SDL_SOUND_H
124
150
        // init sound-file-system of SDL
170
196
                {
171
197
                        m_frames = m_origFrames;
172
198
                        m_startFrame = 0;
173
 
                        m_endFrame = m_frames-1;
 
199
                        if( m_frames > 0 )
 
200
                        {
 
201
                                m_endFrame = m_frames - 1;
 
202
                        }
 
203
                        else
 
204
                        {
 
205
                                m_endFrame = 0;
 
206
                        }
174
207
                }
175
208
        }
176
209
        else if( m_audioFile != "" )
192
225
                Sint16 * buf = NULL;
193
226
                Uint8 channels;
194
227
 
 
228
#ifdef HAVE_SNDFILE_H
 
229
                if( m_frames == 0 )
 
230
                {
 
231
                        m_frames = decodeSampleSF( f, buf, channels );
 
232
                }
 
233
#endif
195
234
#ifdef SDL_SDL_SOUND_H
196
235
                if( m_frames == 0 )
197
236
                {
198
237
                        m_frames = decodeSampleSDL( f, buf, channels );
199
238
                }
200
239
#endif
201
 
#ifdef HAVE_SNDFILE_H
202
 
                if( m_frames == 0 )
203
 
                {
204
 
                        m_frames = decodeSampleSF( f, buf, channels );
205
 
                }
206
 
#endif
207
240
#ifdef HAVE_VORBIS_VORBISFILE_H
208
241
                if( m_frames == 0 )
209
242
                {
216
249
                        {
217
250
                                // update frame-variables
218
251
                                m_startFrame = 0;
219
 
                                m_endFrame = m_frames - 1;
 
252
                                if( m_frames > 0 )
 
253
                                {
 
254
                                        m_endFrame = m_frames - 1;
 
255
                                }
 
256
                                else
 
257
                                {
 
258
                                        m_endFrame = 0;
 
259
                                }
220
260
                        }
221
261
 
222
262
                        // following code transforms int-samples into
261
301
                else
262
302
                {
263
303
                        m_data = new sampleFrame[1];
264
 
                        for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
265
 
                        {
266
 
                                m_data[0][chnl] = 0.0f;
267
 
                        }
 
304
                        memset( m_data, 0, sizeof( *m_data ) );
268
305
                        m_frames = 1;
 
306
                        m_startFrame = 0;
 
307
                        m_endFrame = 1;
269
308
                }
270
309
        }
271
310
        else
272
311
        {
273
312
                m_data = new sampleFrame[1];
274
 
                for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
275
 
                {
276
 
                        m_data[0][chnl] = 0.0f;
277
 
                }
 
313
                memset( m_data, 0, sizeof( *m_data ) * 1 );
278
314
                m_frames = 1;
 
315
                m_startFrame = 0;
 
316
                m_endFrame = 1;
279
317
        }
280
318
 
281
319
        m_dataMutex.unlock();
300
338
 
301
339
        Sound_Sample * snd_sample = Sound_NewSampleFromFile( _f,
302
340
                                                &STD_AUDIO_INFO, 16384 );
303
 
        // file not found?
 
341
        // file found?
304
342
        if( snd_sample != NULL )
305
343
        {
306
344
                // let SDL_sound decode our file to requested format
361
399
// callback-functions for reading ogg-file
362
400
 
363
401
#ifndef QT4
364
 
#define read readBlock
365
 
#define seek at 
366
 
#define pos at
367
402
#endif
368
403
 
369
404
size_t qfileReadCallback( void * _ptr, size_t _size, size_t _n, void * _udata )
411
446
        return( static_cast<QFile *>( _udata )->pos() );
412
447
}
413
448
 
414
 
#undef read
415
 
#undef seek
416
 
#undef pos
417
449
 
418
450
 
419
451
 
529
561
{
530
562
        int error;
531
563
        SRC_STATE * state;
532
 
        if( ( state = src_new(
533
 
#ifdef HQ_SINC
534
 
                                        SRC_SINC_MEDIUM_QUALITY,
535
 
#else
536
 
                                        SRC_ZERO_ORDER_HOLD,
537
 
#endif
 
564
        if( ( state = src_new(/*
 
565
                ( mixer::inst()->highQuality() == TRUE ) ?
 
566
                                        SRC_SINC_FASTEST :*/
 
567
                                        SRC_LINEAR,
538
568
                                        DEFAULT_CHANNELS, &error ) ) == NULL )
539
569
        {
540
570
                printf( "Error: src_new() failed in sample_buffer.cpp!\n" );
566
596
                return( FALSE );
567
597
        }
568
598
 
569
 
        const float freq_factor = 1.0f / (BASE_FREQ / _freq);
 
599
        const double freq_factor = (double) _freq / (double) BASE_FREQ;
570
600
        const Sint16 freq_diff = static_cast<Sint16>( BASE_FREQ - _freq );
571
601
 
572
602
        Uint32 frames_to_process = _frames;
579
609
        {
580
610
                return( FALSE );
581
611
        }
 
612
 
 
613
        // do we have frames left?? this is only important when not in
 
614
        // looping-mode because in looping-mode we loop to start-frame...
 
615
        if( _start_frame >= total_frames_for_current_pitch && _looped == FALSE )
 
616
        {
 
617
                return( FALSE );
 
618
        }
 
619
 
582
620
        // this holds the number of the first frame to play
583
621
        const Uint32 play_frame = m_startFrame + ( _start_frame %
584
622
                                        total_frames_for_current_pitch );
587
625
        Uint32 frames_for_loop = total_frames_for_current_pitch -
588
626
                                                ( play_frame - m_startFrame );
589
627
 
590
 
        // do we have frames left?? this is only important when not in
591
 
        // looping-mode because in looping-mode we loop to start-frame...
592
 
        if( _start_frame >= total_frames_for_current_pitch && _looped == FALSE )
593
 
        {
594
 
                return( FALSE );
595
 
        }
596
 
 
597
628
        // make sure, data isn't accessed in any other way (e.g. deleting
598
629
        // of this buffer...)
599
630
        m_dataMutex.lock();
602
633
        {
603
634
                frames_to_process = frames_for_loop;
604
635
        }
605
 
 
 
636
        const Uint32 f1 = static_cast<Uint32>( play_frame * freq_factor );
 
637
/*      Uint32 f2 = 0;
 
638
        while( f2 < f1 )
 
639
        {
 
640
                f2 += frames_to_process * freq_factor;
 
641
        }
 
642
        if( f2 > f1 && f2 >= frames_to_process )
 
643
        {
 
644
                f2 -= frames_to_process * freq_factor;
 
645
        }*/
 
646
//      static int foo = 0;
606
647
        // calc pointer of first frame
607
 
        sampleFrame * start_frame = (sampleFrame *) m_data +
608
 
                                        static_cast<Uint32>( play_frame *
609
 
                                                                freq_factor );
 
648
        sampleFrame * start_frame = (sampleFrame *) m_data + f1;
 
649
        //printf("diff:%d %f  %d f2: %d  input: %d\n", f2 -foo, play_frame * freq_factor, static_cast<Uint32>( play_frame * freq_factor ), f2, (Uint32)( frames_for_loop * freq_factor ) );
 
650
//      foo = f2;
610
651
        sampleFrame * loop_start = start_frame;
611
652
 
612
653
        // check whether we have to change pitch...
637
678
#else
638
679
                Uint32 src_frame_base = 0;
639
680
                // check whether we're in high-quality-mode
640
 
                if( mixer::inst()->highQuality() )
 
681
                if( mixer::inst()->highQuality() == TRUE )
641
682
                {
642
683
                        // we are, so let's use cubic interpolation...
643
684
                        for( Uint32 frame = 0; frame < frames_to_process;
755
796
 
756
797
void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm )
757
798
{
758
 
        _p.setClipRect( _dr );
759
 
        _p.setPen (QColor(0x22, 0xFF, 0x44));
 
799
//      _p.setClipRect( _dr );
 
800
//      _p.setPen( QColor( 0x22, 0xFF, 0x44 ) );
 
801
        //_p.setPen( QColor( 64, 224, 160 ) );
760
802
#ifdef QT4
761
803
        // TODO: save and restore aa-settings
762
804
        _p.setRenderHint( QPainter::Antialiasing );
764
806
        const int w = _dr.width();
765
807
        const int h = _dr.height();
766
808
 
767
 
        const Uint16 y_base = h/2+_dr.y();
768
 
        const float y_space = h/2;
 
809
        const Uint16 y_base = h / 2 + _dr.y();
 
810
        const float y_space = h / 2;
769
811
 
770
812
        if( m_data == NULL || m_frames == 0 )
771
813
        {
772
 
                _p.drawLine( _dr.x(), y_base, _dr.x()+w, y_base );
 
814
                _p.drawLine( _dr.x(), y_base, _dr.x() + w, y_base );
773
815
                return;
774
816
        }
775
817
        else if( _dm == LINE_CONNECT )
805
847
                {
806
848
                        const int x = static_cast<int>( frame /
807
849
                                                        (float) m_frames * w ) +
808
 
                                        _dr.x();
 
850
                                                                _dr.x();
809
851
                        for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
810
852
                        {
811
853
                                const Uint16 y = y_base +
812
 
                        static_cast<Uint16>( m_data[frame][chnl]*y_space );
 
854
                        static_cast<Uint16>( m_data[frame][chnl] * y_space );
813
855
                                _p.drawLine( old_x, old_y[chnl], x, y );
814
856
                                old_y[chnl] = y;
815
857
                        }
826
868
                        for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
827
869
                        {
828
870
                                _p.drawPoint( x, y_base +
829
 
                                        static_cast<Uint16>(
830
 
                                                m_data[frame][chnl]*y_space ) );
 
871
                        static_cast<Uint16>( m_data[frame][chnl] * y_space ) );
831
872
                        }
832
873
                }
833
874
        }
834
 
        _p.setClipping( FALSE );
 
875
//      _p.setClipping( FALSE );
835
876
}
836
877
 
837
878
 
932
973
}
933
974
 
934
975
 
 
976
#undef HAVE_FLAC_STREAM_ENCODER_H       /* not yet... */
 
977
#undef HAVE_FLAC_STREAM_DECODER_H
 
978
 
 
979
#ifdef HAVE_FLAC_STREAM_ENCODER_H
 
980
FLAC__StreamEncoderWriteStatus flacStreamEncoderWriteCallback(
 
981
                                        const FLAC__StreamEncoder *
 
982
                                                                /*_encoder*/,
 
983
                                        const FLAC__byte _buffer[], 
 
984
                                        unsigned int/* _samples*/,
 
985
                                        unsigned int _bytes,
 
986
                                        unsigned int/* _current_frame*/,
 
987
                                        void * _client_data )
 
988
{
 
989
/*      if( _bytes == 0 )
 
990
        {
 
991
                return( FLAC__STREAM_ENCODER_WRITE_STATUS_OK );
 
992
        }*/
 
993
        return( ( static_cast<QBuffer *>( _client_data )->write(
 
994
                                (const char *) _buffer, _bytes ) ==
 
995
                                                                (int) _bytes ) ?
 
996
                                FLAC__STREAM_ENCODER_WRITE_STATUS_OK :
 
997
                                FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR );
 
998
}
 
999
 
 
1000
 
 
1001
void flacStreamEncoderMetadataCallback( const FLAC__StreamEncoder *,
 
1002
                                        const FLAC__StreamMetadata * _metadata,
 
1003
                                        void * _client_data )
 
1004
{
 
1005
        QBuffer * b = static_cast<QBuffer *>( _client_data );
 
1006
        b->seek( 0 );
 
1007
        b->write( (const char *) _metadata, sizeof( *_metadata ) );
 
1008
}
 
1009
 
 
1010
#endif
 
1011
 
 
1012
 
 
1013
QString sampleBuffer::toBase64( void ) const
 
1014
{
 
1015
        if( m_data == NULL || m_frames == 0 )
 
1016
        {
 
1017
                return( "" );
 
1018
        }
 
1019
#ifdef HAVE_FLAC_STREAM_ENCODER_H
 
1020
        const Uint32 FRAMES_PER_BUF = 1152;
 
1021
 
 
1022
        FLAC__StreamEncoder * flac_enc = FLAC__stream_encoder_new();
 
1023
        FLAC__stream_encoder_set_channels( flac_enc, DEFAULT_CHANNELS );
 
1024
        FLAC__stream_encoder_set_blocksize( flac_enc, FRAMES_PER_BUF );
 
1025
/*      FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, TRUE );
 
1026
        FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, TRUE );*/
 
1027
        FLAC__stream_encoder_set_sample_rate( flac_enc,
 
1028
                                                mixer::inst()->sampleRate() );
 
1029
        QBuffer ba_writer;
 
1030
#ifdef QT4
 
1031
        ba_writer.open( QBuffer::WriteOnly );
 
1032
#else
 
1033
        ba_writer.open( IO_WriteOnly );
 
1034
#endif
 
1035
 
 
1036
        FLAC__stream_encoder_set_write_callback( flac_enc,
 
1037
                                        flacStreamEncoderWriteCallback );
 
1038
        FLAC__stream_encoder_set_metadata_callback( flac_enc,
 
1039
                                        flacStreamEncoderMetadataCallback );
 
1040
        FLAC__stream_encoder_set_client_data( flac_enc, &ba_writer );
 
1041
        if( FLAC__stream_encoder_init( flac_enc ) != FLAC__STREAM_ENCODER_OK )
 
1042
        {
 
1043
                printf( "error within FLAC__stream_encoder_init()!\n" );
 
1044
        }
 
1045
        Uint32 frame_cnt = 0;
 
1046
        while( frame_cnt < m_frames )
 
1047
        {
 
1048
                Uint32 remaining = tMin<Uint32>( FRAMES_PER_BUF,
 
1049
                                                        m_frames - frame_cnt );
 
1050
                FLAC__int32 buf[FRAMES_PER_BUF * DEFAULT_CHANNELS];
 
1051
                for( Uint32 f = 0; f < remaining; ++f )
 
1052
                {
 
1053
                        for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
 
1054
                        {
 
1055
                                buf[f*DEFAULT_CHANNELS+ch] = (FLAC__int32)(
 
1056
                                        mixer::clip( m_data[f+frame_cnt][ch] ) *
 
1057
                                                OUTPUT_SAMPLE_MULTIPLIER );
 
1058
                        }
 
1059
                }
 
1060
                FLAC__stream_encoder_process_interleaved( flac_enc, buf,
 
1061
                                                                remaining );
 
1062
                frame_cnt += remaining;
 
1063
        }
 
1064
        FLAC__stream_encoder_finish( flac_enc );
 
1065
        FLAC__stream_encoder_delete( flac_enc );
 
1066
        printf("%d %d\n", frame_cnt, (int)ba_writer.size() );
 
1067
        ba_writer.close();
 
1068
#ifdef QT4
 
1069
        return( ba_writer.data().toBase64() );
 
1070
#else
 
1071
        QByteArray ba = ba_writer.buffer();
 
1072
        const Uint32 ssize = ba.size();
 
1073
        const Uint8 * src = (const Uint8 *) ba.data();
 
1074
#endif
 
1075
 
 
1076
#else   /* HAVE_FLAC_STREAM_ENCODER_H */
 
1077
 
 
1078
#ifdef QT4
 
1079
        return( QByteArray( (const char *) m_data, m_frames *
 
1080
                                        sizeof( sampleFrame ) ).toBase64() );
 
1081
#else
 
1082
        const Uint32 ssize = m_frames * sizeof( sampleFrame );
 
1083
        const Uint8 * src = (const Uint8 *) m_data;
 
1084
#endif
 
1085
 
 
1086
#endif  /* HAVE_FLAC_STREAM_ENCODER_H */
 
1087
 
 
1088
 
 
1089
#ifndef QT4
 
1090
        // code mostly taken from
 
1091
        // qt-x11-opensource-src-4.0.1/src/corelib/tools/qbytearray.cpp
 
1092
 
 
1093
        const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
 
1094
                                "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
 
1095
        const char padchar = '=';
 
1096
        int padlen = 0;
 
1097
 
 
1098
        const Uint32 dsize = ( ( ssize * 4 ) / 3 ) + 3;
 
1099
        char * ptr = new char[dsize + 1];
 
1100
        char * out = ptr;
 
1101
 
 
1102
        Uint32 i = 0;
 
1103
        while( i < ssize )
 
1104
        {
 
1105
                Uint32 chunk = 0;
 
1106
                chunk |= Uint32( src[i++] ) << 16;
 
1107
                if( i == dsize )
 
1108
                {
 
1109
                        padlen = 2;
 
1110
                }
 
1111
                else
 
1112
                {
 
1113
                        chunk |= Uint32( src[i++] ) << 8;
 
1114
                        if( i == ssize )
 
1115
                        {
 
1116
                                padlen = 1;
 
1117
                        }
 
1118
                        else
 
1119
                        {
 
1120
                                chunk |= Uint32( src[i++] );
 
1121
                        }
 
1122
                }
 
1123
 
 
1124
                Uint32 j = ( chunk & 0x00fc0000 ) >> 18;
 
1125
                Uint32 k = ( chunk & 0x0003f000 ) >> 12;
 
1126
                Uint32 l = ( chunk & 0x00000fc0 ) >> 6;
 
1127
                Uint32 m = ( chunk & 0x0000003f );
 
1128
                *out++ = alphabet[j];
 
1129
                *out++ = alphabet[k];
 
1130
                if( padlen > 1 )
 
1131
                {
 
1132
                        *out++ = padchar;
 
1133
                }
 
1134
                else
 
1135
                {
 
1136
                        *out++ = alphabet[l];
 
1137
                }
 
1138
                if( padlen > 0 )
 
1139
                {
 
1140
                        *out++ = padchar;
 
1141
                }
 
1142
                else
 
1143
                {
 
1144
                        *out++ = alphabet[m];
 
1145
                }
 
1146
        }
 
1147
        // terminate string
 
1148
        ptr[out - ptr] = 0;
 
1149
        QString s( ptr );
 
1150
        delete[] ptr;
 
1151
        return( s );
 
1152
#endif
 
1153
}
 
1154
 
 
1155
 
935
1156
 
936
1157
 
937
1158
void sampleBuffer::setAudioFile( const QString & _audio_file )
955
1176
 
956
1177
 
957
1178
 
 
1179
#ifdef HAVE_FLAC_STREAM_DECODER_H
 
1180
 
 
1181
struct flacStreamDecoderClientData
 
1182
{
 
1183
        QBuffer * read_buffer;
 
1184
        QBuffer * write_buffer;
 
1185
} ;
 
1186
 
 
1187
 
 
1188
 
 
1189
FLAC__StreamDecoderReadStatus flacStreamDecoderReadCallback(
 
1190
                                        const FLAC__StreamDecoder *
 
1191
                                                                /*_decoder*/,
 
1192
                                        FLAC__byte * _buffer,
 
1193
                                        unsigned int * _bytes,
 
1194
                                        void * _client_data )
 
1195
{
 
1196
        int res = static_cast<flacStreamDecoderClientData *>(
 
1197
                                        _client_data )->read_buffer->read(
 
1198
                                                (char *) _buffer, *_bytes );
 
1199
 
 
1200
        if( res > 0 )
 
1201
        {
 
1202
                *_bytes = res;
 
1203
                return( FLAC__STREAM_DECODER_READ_STATUS_CONTINUE );
 
1204
 
 
1205
        }
 
1206
        *_bytes = 0;
 
1207
        return( FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM );
 
1208
}
 
1209
 
 
1210
 
 
1211
 
 
1212
 
 
1213
FLAC__StreamDecoderWriteStatus flacStreamDecoderWriteCallback(
 
1214
                                        const FLAC__StreamDecoder *
 
1215
                                                                /*_decoder*/,
 
1216
                                        const FLAC__Frame * _frame,
 
1217
                                        const FLAC__int32 * const _buffer[],
 
1218
                                        void * _client_data )
 
1219
{
 
1220
        if( _frame->header.channels != 2 )
 
1221
        {
 
1222
                printf( "channels != 2 in "
 
1223
                                        "flacStreamDecoderWriteCallback()\n" );
 
1224
                return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT );
 
1225
        }
 
1226
 
 
1227
        if( _frame->header.bits_per_sample != 16 )
 
1228
        {
 
1229
                printf( "bits_per_sample != 16 in "
 
1230
                                        "flacStreamDecoderWriteCallback()\n" );
 
1231
                return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT );
 
1232
        }
 
1233
 
 
1234
        const Uint32 frames = _frame->header.blocksize;
 
1235
        for( Uint32 frame = 0; frame < frames; ++frame )
 
1236
        {
 
1237
                sampleFrame sframe = { _buffer[0][frame] /
 
1238
                                                OUTPUT_SAMPLE_MULTIPLIER,
 
1239
                                        _buffer[1][frame] /
 
1240
                                                OUTPUT_SAMPLE_MULTIPLIER
 
1241
                                        } ;
 
1242
                static_cast<flacStreamDecoderClientData *>(
 
1243
                                        _client_data )->write_buffer->write(
 
1244
                                (const char *) sframe, sizeof( sframe ) );
 
1245
        } 
 
1246
        return( FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE );
 
1247
}
 
1248
 
 
1249
 
 
1250
void flacStreamDecoderMetadataCallback( const FLAC__StreamDecoder *,
 
1251
                                        const FLAC__StreamMetadata *,
 
1252
                                        void * /*_client_data*/ )
 
1253
{
 
1254
        printf("stream decoder metadata callback\n");
 
1255
/*      QBuffer * b = static_cast<QBuffer *>( _client_data );
 
1256
        b->seek( 0 );
 
1257
        b->write( (const char *) _metadata, sizeof( *_metadata ) );*/
 
1258
}
 
1259
 
 
1260
 
 
1261
void flacStreamDecoderErrorCallback( const FLAC__StreamDecoder *,
 
1262
                                        FLAC__StreamDecoderErrorStatus _status,
 
1263
                                        void * /*_client_data*/ )
 
1264
{
 
1265
        printf("error callback! %d\n", _status);
 
1266
        // what to do now??
 
1267
}
 
1268
 
 
1269
#endif
 
1270
 
 
1271
 
 
1272
void sampleBuffer::loadFromBase64( const QString & _data )
 
1273
{
 
1274
#ifdef QT4
 
1275
        QByteArray orig_data = QByteArray::fromBase64( _data.toAscii() );
 
1276
#else
 
1277
        const char * src = _data.ascii();
 
1278
        csize ssize = _data.length();
 
1279
        csize dsize = ( _data.length() * 3 ) / 4;
 
1280
        char * dst = new char[dsize]; 
 
1281
 
 
1282
        // code mostly taken from
 
1283
        // qt-x11-opensource-src-4.0.1/src/corelib/tools/qbytearray.cpp
 
1284
        unsigned int buf = 0;
 
1285
        int nbits = 0;
 
1286
        int offset = 0;
 
1287
 
 
1288
        for( csize i = 0; i < ssize; ++i )
 
1289
        {
 
1290
                int ch = src[i];
 
1291
                int d;
 
1292
 
 
1293
                if( ch >= 'A' && ch <= 'Z' )
 
1294
                {
 
1295
                        d = ch - 'A';
 
1296
                }
 
1297
                else if( ch >= 'a' && ch <= 'z' )
 
1298
                {
 
1299
                        d = ch - 'a' + 26;
 
1300
                }
 
1301
                else if( ch >= '0' && ch <= '9' )
 
1302
                {
 
1303
                        d = ch - '0' + 52;
 
1304
                }
 
1305
                else if( ch == '+' )
 
1306
                {
 
1307
                        d = 62;
 
1308
                }
 
1309
                else if( ch == '/' )
 
1310
                {
 
1311
                        d = 63;
 
1312
                }
 
1313
                else
 
1314
                {
 
1315
                        d = -1;
 
1316
                }
 
1317
 
 
1318
                if( d != -1 )
 
1319
                {
 
1320
                        buf = ( buf << 6 ) | (Uint32)d;
 
1321
                        nbits += 6;
 
1322
                        if( nbits >= 8 )
 
1323
                        {
 
1324
                                nbits -= 8;
 
1325
                                dst[offset++] = buf >> nbits;
 
1326
                                buf &= ( 1 << nbits ) - 1;
 
1327
                        }
 
1328
                }
 
1329
        }
 
1330
        QByteArray orig_data;
 
1331
        orig_data.setRawData( dst, dsize );
 
1332
#endif
 
1333
#ifdef HAVE_FLAC_STREAM_DECODER_H
 
1334
 
 
1335
#ifdef QT4
 
1336
        QBuffer ba_reader( &orig_data );
 
1337
        ba_reader.open( QBuffer::ReadOnly );
 
1338
#else
 
1339
        QBuffer ba_reader( orig_data );
 
1340
        ba_reader.open( IO_ReadOnly );
 
1341
#endif
 
1342
 
 
1343
        QBuffer ba_writer;
 
1344
#ifdef QT4
 
1345
        ba_writer.open( QBuffer::WriteOnly );
 
1346
#else
 
1347
        ba_writer.open( IO_WriteOnly );
 
1348
#endif
 
1349
 
 
1350
        flacStreamDecoderClientData cdata = { &ba_reader, &ba_writer } ;
 
1351
 
 
1352
        FLAC__StreamDecoder * flac_dec = FLAC__stream_decoder_new();
 
1353
 
 
1354
        FLAC__stream_decoder_set_read_callback( flac_dec,
 
1355
                                        flacStreamDecoderReadCallback );
 
1356
        FLAC__stream_decoder_set_write_callback( flac_dec,
 
1357
                                        flacStreamDecoderWriteCallback );
 
1358
        FLAC__stream_decoder_set_error_callback( flac_dec,
 
1359
                                        flacStreamDecoderErrorCallback );
 
1360
        FLAC__stream_decoder_set_metadata_callback( flac_dec,
 
1361
                                        flacStreamDecoderMetadataCallback );
 
1362
        FLAC__stream_decoder_set_client_data( flac_dec, &cdata );
 
1363
 
 
1364
        FLAC__stream_decoder_init( flac_dec );
 
1365
 
 
1366
        FLAC__stream_decoder_process_until_end_of_stream( flac_dec );
 
1367
 
 
1368
        FLAC__stream_decoder_finish( flac_dec );
 
1369
        FLAC__stream_decoder_delete( flac_dec );
 
1370
 
 
1371
        orig_data = ba_writer.buffer();
 
1372
        printf("%d\n", (int) orig_data.size() );
 
1373
#endif
 
1374
        m_origFrames = orig_data.size() / sizeof( sampleFrame ); 
 
1375
        delete[] m_origData;
 
1376
        m_origData = new sampleFrame[m_origFrames];
 
1377
        memcpy( m_origData, orig_data.data(), orig_data.size() );
 
1378
        update();
 
1379
#ifndef QT4
 
1380
//      delete[] dst;
 
1381
#endif
 
1382
}
 
1383
 
 
1384
 
 
1385
 
958
1386
 
959
1387
void sampleBuffer::setStartFrame( Uint32 _s )
960
1388
{
1009
1437
}
1010
1438
 
1011
1439
 
 
1440
#undef write
 
1441
#undef read
 
1442
#undef seek
 
1443
#undef pos
 
1444
 
1012
1445
 
1013
1446
#include "sample_buffer.moc"
1014
1447