You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
k3b/libk3b/plugin/k3baudiodecoder.h

257 lines
7.3 KiB

/*
*
* $Id: k3baudiodecoder.h 619556 2007-01-03 17:38:12Z trueg $
* Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
*
* This file is part of the K3b project.
* Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
*
* 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 <k3bplugin.h>
#include <k3bmsf.h>
#include "k3b_export.h"
#include <kurl.h>
/**
* 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
{
Q_OBJECT
TQ_OBJECT
public:
K3bAudioDecoder( TQObject* tqparent = 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
{
Q_OBJECT
TQ_OBJECT
public:
K3bAudioDecoderFactory( TQObject* tqparent = 0, const char* name = 0 )
: K3bPlugin( tqparent, 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* tqparent = 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