-rw-r--r-- | core/multimedia/opieplayer/wavplugin/wavplugin.cpp | 424 | ||||
-rw-r--r-- | core/multimedia/opieplayer/wavplugin/wavplugin.h | 5 | ||||
-rw-r--r-- | core/multimedia/opieplayer/wavplugin/wavpluginimpl.h | 2 |
3 files changed, 140 insertions, 291 deletions
diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp index 0be667f..7ac63c0 100644 --- a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp +++ b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp @@ -1,494 +1,340 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ +// L.J.Potter added changes Fri 02-15-2002 + #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <qfile.h> #include "wavplugin.h" //#define debugMsg(a) qDebug(a) #define debugMsg(a) struct RiffChunk { char id[4]; Q_UINT32 size; char data[4]; }; struct ChunkData { Q_INT16 formatTag; Q_INT16 channels; Q_INT32 samplesPerSec; Q_INT32 avgBytesPerSec; Q_INT16 blockAlign; Q_INT16 wBitsPerSample; }; -const int sound_buffer_size = 4096; +const int sound_buffer_size = 512; // 4096; // you got to be kidding right? class WavPluginData { public: QFile *input; int wavedata_remaining; ChunkData chunkdata; RiffChunk chunk; uchar data[sound_buffer_size+32]; // +32 to handle badly aligned input data int out,max; int samples_due; int samples; - int freq; - int chan; - int sampleRate; - int resolution; - + WavPluginData() { - max = out = sound_buffer_size; - wavedata_remaining = 0; - samples_due = 0; - samples = -1; + max = out = sound_buffer_size; + wavedata_remaining = 0; + samples_due = 0; + samples = -1; } - // expands out samples to the frequency of 44kHz + // expands out samples to the frequency of 44kHz bool add( short *output, long count, long& done, bool stereo ) - { - qDebug("add"); - done = 0; - - if ( input == 0 ) { - qDebug("no input"); + { + done = 0; + qApp->processEvents(); + + if ( input == 0 ) { + qDebug("no input"); + return FALSE; + } + + while ( count ) { + int l,r; + if ( getSample(l, r) == FALSE ) { + qDebug("didn't get sample"); return FALSE; } - - while ( count ) { - int l,r; - if ( getSample(l, r) == FALSE ) { - qDebug("didn't get sample"); - return FALSE; - } - samples_due += 44100; - while ( count && (samples_due > chunkdata.samplesPerSec) ) { - *output++ = l; - if ( stereo ) - *output++ = r; - samples_due -= chunkdata.samplesPerSec; - count--; - done++; - } + samples_due += chunkdata.samplesPerSec; + while ( count && (samples_due > chunkdata.samplesPerSec) ) { + *output++ = l; + if ( stereo ) + *output++ = r; + samples_due -= chunkdata.samplesPerSec; + count--; + done++; } - - return TRUE; } + return TRUE; + } bool initialise() { - qDebug("initialize"); - if ( input == 0 ) - return FALSE; - - wavedata_remaining = -1; - - while ( wavedata_remaining == -1 ) { - // Keep reading chunks... - const int n = sizeof(chunk) - sizeof(chunk.data); - int t = input->readBlock( (char*)&chunk, n ); - if ( t != n ) { - if ( t == -1 ) - return FALSE; - return TRUE; - } - if ( qstrncmp(chunk.id,"data",4) == 0 ) { - samples = wavedata_remaining = chunk.size; - } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) { - char d[4]; - if ( input->readBlock(d,4) != 4 ) { - return FALSE; - } - if ( qstrncmp(d,"WAVE",4) != 0 ) { - // skip - if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) { - return FALSE; - } - } - } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { - if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) { - return FALSE; - } -#define WAVE_FORMAT_PCM 1 - if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { - qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); - return FALSE; - } - } - + if ( input == 0 ) + return FALSE; + wavedata_remaining = -1; - - else { - // ignored chunk - if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) { - return FALSE; - } - } - } // while - - return TRUE; + while ( wavedata_remaining == -1 ) { + // Keep reading chunks... + const int n = sizeof(chunk) - sizeof(chunk.data); + int t = input->readBlock( (char*)&chunk, n ); + if ( t != n ) { + if ( t == -1 ) + return FALSE; + return TRUE; + } + if ( qstrncmp(chunk.id,"data",4) == 0 ) { + samples = wavedata_remaining = chunk.size; + } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) { + char d[4]; + if ( input->readBlock(d,4) != 4 ) { + return FALSE; + } + if ( qstrncmp(d,"WAVE",4) != 0 ) { + // skip + if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) { + return FALSE; + } + } + } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) { + if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) { + return FALSE; + } +#define WAVE_FORMAT_PCM 1 + if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) { + qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag); + return FALSE; + } + } else { + // ignored chunk + if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) { + return FALSE; + } + } + } // while + qDebug("bits %d", chunkdata.wBitsPerSample); + return TRUE; } - // gets a sample from the file + // gets a sample from the file bool getSample(int& l, int& r) - { - l = r = 0; - - if ( input == 0 ) - return FALSE; + { + l = r = 0; - if ( (wavedata_remaining < 0) || !max ) - return FALSE; - - if ( out >= max ) { - max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) ); + if ( input == 0 ) + return FALSE; - wavedata_remaining -= max; - - out = 0; - if ( max <= 0 ) { - max = 0; - return TRUE; - } - } - if ( resolution == 8 ) { - l = (data[out++] - 128) * 128; - } else { - l = ((short*)data)[out/2]; - out += 2; - } - if ( chan == 1 ) { - r = l; - } else { - if ( resolution == 8 ) { - r = (data[out++] - 128) * 128; - } else { - r = ((short*)data)[out/2]; - out += 2; - } - } - return TRUE; - } // getSample - -////////////////////////////////////////////////////// -int getWavSettings(int fd) -{ //this came from wmrecord - - char t1[4]; - unsigned long l1; - int found; - short fmt; - unsigned short ch, brate; - unsigned long srate; - - - /* First read in the RIFF identifier. If this is missing then the - * file is not a valid WAVE file. - */ - if (read(fd, t1, 4)<4) { - qDebug(" Could not read from sound file.\n"); - return -1; - } - if (strncmp(t1, "RIFF", 4)) { - qDebug(" not a valid WAV file.\n"); - return -1; - } - /* Advance the file pointer to the next relevant field. */ - lseek(fd, 4, SEEK_CUR); - /* Read in the WAVE identifier. */ - if (read(fd, t1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - if (strncmp(t1, "WAVE", 4)) { - qDebug("not a valid WAV file.\n"); - return -1; - } + if ( (wavedata_remaining < 0) || !max ) + return FALSE; - /* Search through the file for the format chunk. If the end of the - * file is reached without finding the chunk, then the file is not a - * valid WAVE file. - */ - found = 0; - while (!found) { - if (read(fd, t1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - if (strncmp(t1, "fmt ", 4)) { - /* Determine the length of the chunk found and skip to the next - * chunk. The chunk length is always stored in the four bytes - * following the chunk id. - */ - if (read(fd, &l1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - lseek(fd, l1, SEEK_CUR); - } - else { - /* This is the format chunk, which stores the playback settings - * for the recording. - */ - /* Skip the length field, since we don't really need it. */ - lseek(fd, 4, SEEK_CUR); - /* Read in the format tag. If it has a value of 1, then there is - * no compression and we can attempt to play the file - * back. Otherwise, return. - */ - if (read(fd, &fmt, 2)<2) { - qDebug("Could not read from format chunk.\n"); - return -1; - } - if (fmt != 1) { - qDebug("Wave file contains compressed data." - " Unable to continue.\n"); - return -1; - } - /* Get the stereo mode. */ - if (read(fd, &ch, 2)<2) { - qDebug("Could not read from format chunk.\n"); - return -1; - } - else { - chan = ch; - qDebug("File has %d channels", chan); - } - /* Get the sample rate. */ - if (read(fd, &srate, 4)<4) { - qDebug("Could not read from format chunk.\n"); - return -1; - } - else { - sampleRate = srate; - qDebug("File has samplerate of %d", sampleRate); - } - /* Get the bit rate. This is at the end of the format chunk. */ - lseek(fd, 6, SEEK_CUR); - if (read(fd, &brate, 2)<2) { - qDebug("Could not read from format chunk.\n"); - return -1; - } - else { - resolution = brate; - qDebug("File has bitrate of %d", resolution); - } + if ( out >= max ) { + max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) ); - found++; - } - } + wavedata_remaining -= max; - /* Search through the file for the data chunk. If the end of the - * file is reached without finding the chunk, then the file is not a - * valid WAVE file. - */ - found = 0; - while (!found) { - if (read(fd, t1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - if (strncmp(t1, "data", 4)) { - /* Determine the length of the chunk found and skip to the next - * chunk. The chunk length is always stored in the four bytes - * following the chunk id. - */ - if (read(fd, &l1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - lseek(fd, l1, SEEK_CUR); - } - else { - /* This is the data chunk, which stores the recording. */ - /* Get the length field. */ - if (read(fd, &l1, 4)<4) { - qDebug("Could not read from sound file.\n"); - return -1; - } - else { - samples =l1; - qDebug("file has length of %d\nlasting %d seconds",l1, (( l1 / sampleRate) / chan) / 2 ); // ???? - return l1; - } - } - } + out = 0; + if ( max <= 0 ) { + max = 0; + return TRUE; + } + } + if ( chunkdata.wBitsPerSample == 8 ) { + l = (data[out++] - 128) * 128; + } else { + l = ((short*)data)[out/2]; + out += 2; + } + if ( chunkdata.channels == 1 ) { + r = l; + } else { + if ( chunkdata.wBitsPerSample == 8 ) { + r = (data[out++] - 128) * 128; + } else { + r = ((short*)data)[out/2]; + out += 2; + } + } + return TRUE; + } // getSample - return 0; -} - -////////////////////////////////////////////////// }; WavPlugin::WavPlugin() { d = new WavPluginData; d->input = 0; } WavPlugin::~WavPlugin() { close(); delete d; } bool WavPlugin::isFileSupported( const QString& path ) { - debugMsg( "WavPlugin::isFileSupported" ); +// qDebug( "WavPlugin::isFileSupported" ); char *ext = strrchr( path.latin1(), '.' ); // Test file extension if ( ext ) { if ( strncasecmp(ext, ".raw", 4) == 0 ) return TRUE; if ( strncasecmp(ext, ".wav", 4) == 0 ) return TRUE; if ( strncasecmp(ext, ".wave", 4) == 0 ) return TRUE; } return FALSE; } bool WavPlugin::open( const QString& path ) { - qDebug( "WavPlugin::open" ); +// qDebug( "WavPlugin::open" ); d->max = d->out = sound_buffer_size; d->wavedata_remaining = 0; d->samples_due = 0; d->input = new QFile( path ); if ( d->input->open(IO_ReadOnly) == FALSE ) { - qDebug("couldn't open file"); - delete d->input; - d->input = 0; - return FALSE; + qDebug("couldn't open file"); + delete d->input; + d->input = 0; + return FALSE; } - -// d->getWavSettings( d->input.handle()); + d->initialise(); return TRUE; } bool WavPlugin::close() { - qDebug( "WavPlugin::close" ); +// qDebug( "WavPlugin::close" ); d->input->close(); delete d->input; d->input = 0; return TRUE; } bool WavPlugin::isOpen() { - qDebug( "WavPlugin::isOpen" ); +// qDebug( "WavPlugin::isOpen" ); return ( d->input != 0 ); } int WavPlugin::audioStreams() { - qDebug( "WavPlugin::audioStreams" ); +// qDebug( "WavPlugin::audioStreams" ); return 1; } int WavPlugin::audioChannels( int ) { - debugMsg( "WavPlugin::audioChannels" ); - return d->chan; +// qDebug( "WavPlugin::audioChannels" ); + return d->chunkdata.channels;// 2; // ### Always scale audio to stereo samples } int WavPlugin::audioFrequency( int ) { - qDebug( "WavPlugin::audioFrequency" ); - return d->freq; +// qDebug( "WavPlugin::audioFrequency %d", d->chunkdata.samplesPerSec ); + return d->chunkdata.samplesPerSec; //44100; // ### Always scale to frequency of 44100 } int WavPlugin::audioSamples( int ) { - qDebug( "WavPlugin::audioSamples" ); - return d->samples; -// return d->samples * 2 / d->chunkdata.channels; // ### Scaled samples will be made stereo, -// // Therefore if source is mono we will double the number of samples +// qDebug( "WavPlugin::audioSamples" ); + return d->samples / d->chunkdata.channels/2; // ### Scaled samples will be made stereo, + // Therefore if source is mono we will double the number of samples } bool WavPlugin::audioSetSample( long, int ) { - qDebug( "WavPlugin::audioSetSample" ); +// qDebug( "WavPlugin::audioSetSample" ); return FALSE; } long WavPlugin::audioGetSample( int ) { - qDebug( "WavPlugin::audioGetSample" ); +// qDebug( "WavPlugin::audioGetSample" ); return 0; } /* bool WavPlugin::audioReadSamples( short *, int, long, int ) { debugMsg( "WavPlugin::audioReadSamples" ); return FALSE; } bool WavPlugin::audioReReadSamples( short *, int, long, int ) { debugMsg( "WavPlugin::audioReReadSamples" ); return FALSE; } bool WavPlugin::audioReadMonoSamples( short *output, long samples, long& samplesMade, int ) { debugMsg( "WavPlugin::audioReadMonoSamples" ); return !d->add( output, samples, samplesMade, FALSE ); } bool WavPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) { debugMsg( "WavPlugin::audioReadStereoSamples" ); return !d->add( output, samples, samplesMade, TRUE ); } */ bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) { - qDebug( "WavPlugin::audioReadSamples" ); +// qDebug( "WavPlugin::audioReadSamples" ); return d->add( output, samples, samplesMade, channels != 1 ); } double WavPlugin::getTime() { - qDebug( "WavPlugin::getTime" ); +// qDebug( "WavPlugin::getTime" ); return 0.0; } +int WavPlugin::audioBitsPerSample( int ) { +// qDebug( "WavPlugin::audioFormat %d", d->chunkdata.wBitsPerSample ); + return d->chunkdata.wBitsPerSample; // +} + diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.h b/core/multimedia/opieplayer/wavplugin/wavplugin.h index 19d1a8e..6ae6e06 100644 --- a/core/multimedia/opieplayer/wavplugin/wavplugin.h +++ b/core/multimedia/opieplayer/wavplugin/wavplugin.h @@ -1,77 +1,80 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ +// L.J.Potter added changes Fri 02-15-2002 + #ifndef WAV_PLUGIN_H #define WAV_PLUGIN_H #include <qstring.h> #include <qapplication.h> -#include <qpe/mediaplayerplugininterface.h> +#include "../mediaplayerplugininterface.h" // #define OLD_MEDIAPLAYER_API class WavPluginData; class WavPlugin : public MediaPlayerDecoder { public: WavPlugin(); ~WavPlugin(); const char *pluginName() { return "WavPlugin"; } const char *pluginComment() { return "This is a simple plugin for playing wav files"; } double pluginVersion() { return 1.0; } bool isFileSupported( const QString& ); bool open( const QString& ); bool close(); bool isOpen(); const QString &fileInfo() { return strInfo = ""; } // If decoder doesn't support audio then return 0 here int audioStreams(); int audioChannels( int stream ); int audioFrequency( int stream ); + int audioBitsPerSample( int stream ); int audioSamples( int stream ); bool audioSetSample( long sample, int stream ); long audioGetSample( int stream ); #ifdef OLD_MEDIAPLAYER_API bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); bool audioReadSamples( short *output, int channel, long samples, int stream ); bool audioReReadSamples( short *output, int channel, long samples, int stream ); #else bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); #endif // If decoder doesn't support video then return 0 here int videoStreams() { return 0; } int videoWidth( int ) { return 0; } int videoHeight( int ) { return 0; } double videoFrameRate( int ) { return 0.0; } int videoFrames( int ) { return 0; } bool videoSetFrame( long, int ) { return FALSE; } long videoGetFrame( int ) { return 0; } bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; } bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; } bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; } diff --git a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h index 71f5f20..10f9305 100644 --- a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h +++ b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h @@ -1,47 +1,47 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef WAV_PLUGIN_IMPL_H #define WAV_PLUGIN_IMPL_H -#include <qpe/mediaplayerplugininterface.h> +#include "../mediaplayerplugininterface.h" class WavPlugin; class WavPluginImpl : public MediaPlayerPluginInterface { public: WavPluginImpl(); virtual ~WavPluginImpl(); #ifndef QT_NO_COMPONENT QRESULT queryInterface( const QUuid&, QUnknownInterface** ); Q_REFCOUNT #endif virtual MediaPlayerDecoder *decoder(); virtual MediaPlayerEncoder *encoder(); private: WavPlugin *libmadplugin; ulong ref; |