/* * * $Id: k3baudiodecoder.h 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2003 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING" for the exact licensing terms. */ #ifndef _K3B_AUDIO_DECODER_H_ #define _K3B_AUDIO_DECODER_H_ #include #include #include "k3b_export.h" #include /** * Abstract streaming class for all the audio input. * Has to output data in the following format: * MSBLeft LSBLeft MSBRight LSBRight (big endian byte order) * * Instances are created by K3bAudioDecoderFactory **/ class LIBK3B_EXPORT K3bAudioDecoder : public TQObject { TQ_OBJECT public: K3bAudioDecoder( TQObject* parent = 0, const char* name = 0 ); virtual ~K3bAudioDecoder(); /** * Set the file to decode. Be aware that one cannot rely * on the file length until analyseFile() has been called. */ void setFilename( const TQString& ); /** * Since this may take a while depending on the filetype it is best * to run it in a separate thread. * * This method will also call initDecoder(). */ bool analyseFile(); /** * @return true if the file was successfully analysed by analyseFile. */ bool isValid() const; /** * Initialize the decoding. * Normally there is no need to call this as analyseFile already does so. */ bool initDecoder(); /** * initialize the decoding. * @param startOffset the number of frames to skip at the beginning of the file. * * This is the same as calling: initDecoder() and seek(startOffset) */ bool initDecoder( const K3b::Msf& startOffset ); enum MetaDataField { META_TITLE, META_ARTIST, META_SONGWRITER, META_COMPOSER, META_COMMENT }; /** * This should at least support "Title" and "Artist" * * the default implementation returns the infos set via @p addMetaInfo * and uses KFileMetaInfo if none was set */ virtual TQString metaInfo( MetaDataField ); /** * The filetype is only used for informational purposes. * It is not necessary but highly recommended to implement this method * as it enhances usability. * @returne The filetype of the decoded file. */ virtual TQString fileType() const { return TQString(); } /** * This method may be reimplemented to provide technical information about * the file. It should return localized strings. * * the default implementation returns the infos set via @p addTechnicalInfo */ virtual TQStringList supportedTechnicalInfos() const; /** * The framework will call this method with all strings returned by the * supportedTechnicalInfos() method. It should return localized strings. * * the default implementation returns the infos set via @p addTechnicalInfo */ virtual TQString technicalInfo( const TQString& ) const; /** * returnes -1 on error, 0 when finished, length of data otherwise * takes care of padding * calls decodeInternal() to actually decode data * * Fill the data buffer with maximal maxLen bytes. */ int decode( char* data, int maxLen ); /** * Cleanup after decoding like closing files. * Be aware that this is the counterpart to @p initDecoder(). * * There might happen multiple calls to initDecoder() and cleanup(). */ virtual void cleanup(); /** * Seek to the position pos. * Decoding is started new. That means that the data will be padded to * length() - pos. * returnes true on success; */ bool seek( const K3b::Msf& pos ); /** * Be aware that one cannot rely * on the file length until analyseFile() has been called. */ virtual K3b::Msf length() const { return m_length; } const TQString& filename() const { return m_fileName; } // some helper methods static void fromFloatTo16BitBeSigned( float* src, char* dest, int samples ); static void from16bitBeSignedToFloat( char* src, float* dest, int samples ); static void from8BitTo16BitBeSigned( char* src, char* dest, int samples ); protected: /** * Use this method if using the default implementation of @p metaInfo */ void addMetaInfo( MetaDataField, const TQString& ); /** * Use this method if using the default implementation of @p technicalInfo * and @p supportedTechnicalInfos. */ void addTechnicalInfo( const TQString&, const TQString& ); /** * This will be called once before the first call to decodeInternal. * Use it to initialize decoding structures if necessary. * * There might happen multiple calls to initDecoder() and cleanup(). */ virtual bool initDecoderInternal() = 0; /** * This method should analyze the file to determine the exact length, * the samplerate in Hz, and the number of channels. The framework takes care of * resampling and converting mono to stereo data. * This method may be time consuming. */ virtual bool analyseFileInternal( K3b::Msf& length, int& samplerate, int& channels ) = 0; /** * fill the already allocated data with maximal maxLen bytes of decoded samples. * The framework will take care of padding or cutting the decoded data as well * as resampling to 44100 Hz and converting mono samples to stereo. */ virtual int decodeInternal( char* data, int maxLen ) = 0; virtual bool seekInternal( const K3b::Msf& ) { return false; } private: int resample( char* data, int maxLen ); TQString m_fileName; K3b::Msf m_length; class Private; Private* d; }; /** * PluginFactory that needs to be subclassed in order to create an * audio decoder. * We need this because K3b uses multiple AudioDecoders of the same type at the * same time. */ class LIBK3B_EXPORT K3bAudioDecoderFactory : public K3bPlugin { TQ_OBJECT public: K3bAudioDecoderFactory( TQObject* parent = 0, const char* name = 0 ) : K3bPlugin( parent, name ) { } virtual ~K3bAudioDecoderFactory() { } TQString group() const { return "AudioDecoder"; } /** * K3b uses this flag to decide which plugins to test first * when searching for an audio decoder. * * Decoders that are specialized on one format are favored over * multi-format-decoders. */ virtual bool multiFormatDecoder() const { return false; } /** * This is the most important method of the AudioDecoderFactory. * It is used to determine if a certain file can be decoded by the * decoder this factory creates. * It is important that this method does not work lazy since it will * be called with urls to every kind of files and if it returns true * a decoder of this type is used for the file. */ virtual bool canDecode( const KURL& filename ) = 0; virtual K3bAudioDecoder* createDecoder( TQObject* parent = 0, const char* name = 0 ) const = 0; /** * Searching for an audiodecoder for @p filename. * * It first searches the single format decoder and the the multiformat decoder. * * @returns a newly created decoder on success and 0 when no decoder could be found. */ static K3bAudioDecoder* createDecoder( const KURL& url ); }; #endif