1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-31 09:32:03 +02:00

* Getting rid of old & obsolete audioengine / transcoder stuff.

This commit is contained in:
Christian Muehlhaeuser
2011-02-23 19:05:04 +01:00
parent 755c091a56
commit c50f0626db
28 changed files with 0 additions and 12335 deletions

View File

@@ -1,6 +1,5 @@
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
alsaplayback
tomahawklib
)

View File

@@ -10,8 +10,6 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
/System/Library/Frameworks/DiskArbitration.framework
/System/Library/Frameworks/Foundation.framework
/System/Library/Frameworks/IOKit.framework
rtaudio
)
if (APPLE)

View File

@@ -135,13 +135,10 @@ INCLUDE_DIRECTORIES(
libtomahawk/utils
mac
${THIRDPARTY_DIR}/alsa-playback
${THIRDPARTY_DIR}/rtaudio
${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb/
${THIRDPARTY_DIR}/qtweetlib/qtweetlib/src
${THIRDPARTY_DIR}/qtweetlib/tomahawk-custom
${TAGLIB_INCLUDES}
${LIBECHONEST_INCLUDE_DIR}
)

View File

@@ -13,7 +13,6 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
# third party shipped with tomahawk
${CMAKE_BINARY_DIR}/thirdparty/rtaudio/librtaudio.dll
# system libs
"secur32.dll"

View File

@@ -28,10 +28,6 @@ set( libSources
sip/SipPlugin.cpp
audio/madtranscode.cpp
audio/vorbistranscode.cpp
audio/flactranscode.cpp
audio/audioengine.cpp
database/database.cpp
@@ -168,10 +164,6 @@ set( libHeaders
sip/SipPlugin.h
audio/transcodeinterface.h
audio/madtranscode.h
audio/vorbistranscode.h
audio/flactranscode.h
audio/audioengine.h
database/database.h
@@ -311,8 +303,6 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
${THIRDPARTY_DIR}/libportfwd/include
${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb
${THIRDPARTY_DIR}/rtaudio
${THIRDPARTY_DIR}/alsa-playback
${THIRDPARTY_DIR}/jdns
${THIRDPARTY_DIR}/jdns/jdns
${THIRDPARTY_DIR}/jdns/jdnsshared
@@ -321,13 +311,9 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
IF( WIN32 )
SET( libSources ${libSources} audio/rtaudiooutput.cpp )
SET( libHeaders ${libHeaders} audio/rtaudiooutput.h )
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
# Thirdparty
${CMAKE_BINARY_DIR}/thirdparty/rtaudio/librtaudio.dll
# System
"iphlpapi.a"
"ws2_32.dll"
@@ -343,13 +329,9 @@ IF( APPLE )
FIND_LIBRARY( COREFOUNDATION_LIBRARY CoreFoundation )
MARK_AS_ADVANCED( COREAUDIO_LIBRARY COREFOUNDATION_LIBRARY )
SET( libSources ${libSources} audio/rtaudiooutput.cpp )
SET( libHeaders ${libHeaders} audio/rtaudiooutput.h )
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
# Thirdparty
rtaudio
# System
${COREAUDIO_LIBRARY}
${COREFOUNDATION_LIBRARY}
@@ -360,7 +342,6 @@ IF( UNIX AND NOT APPLE )
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
# Thirdparty
alsaplayback
)
ENDIF( UNIX AND NOT APPLE )
@@ -379,12 +360,6 @@ target_link_libraries( tomahawklib
# Thirdparty shipped with tomahawk
portfwd
# soon to be removed by phonon-dependency
FLAC++
ogg
vorbisfile
mad
# External deps
${TAGLIB_LIBRARIES}
${QJSON_LIBRARIES}

View File

@@ -9,8 +9,6 @@
#include "result.h"
#include "typedefs.h"
#include "transcodeinterface.h"
#include "dllmacro.h"
#define AUDIO_VOLUME_STEP 5

View File

@@ -1,146 +0,0 @@
#include "flactranscode.h"
FLACTranscode::FLACTranscode()
: m_FLACRunning( false )
, m_finished( false )
{
qDebug() << Q_FUNC_INFO;
init();
set_metadata_respond_all();
}
FLACTranscode::~FLACTranscode()
{
qDebug() << Q_FUNC_INFO;
}
void
FLACTranscode::onSeek( int seconds )
{
QMutexLocker locker( &m_mutex );
m_buffer.clear();
m_outBuffer.clear();
}
void
FLACTranscode::clearBuffers()
{
QMutexLocker locker( &m_mutex );
m_FLACRunning = false;
m_finished = false;
m_buffer.clear();
m_outBuffer.clear();
flush();
reset();
}
void
FLACTranscode::processData( const QByteArray& data, bool finish )
{
m_mutex.lock();
m_buffer.append( data );
m_mutex.unlock();
while ( m_buffer.size() >= FLAC_BUFFER )
{
process_single();
}
m_finished = finish;
}
::FLAC__StreamDecoderReadStatus
FLACTranscode::read_callback( FLAC__byte buffer[], size_t *bytes )
{
QMutexLocker locker( &m_mutex );
if ( *bytes > (unsigned int)m_buffer.size() )
*bytes = m_buffer.size();
memcpy( buffer, (char*)m_buffer.data(), *bytes );
m_buffer.remove( 0, *bytes );
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
::FLAC__StreamDecoderWriteStatus
FLACTranscode::write_callback( const ::FLAC__Frame *frame, const FLAC__int32 *const buffer[] )
{
union PCMDATA
{
FLAC__int32 i;
unsigned char b[2];
} pcmDataLeft, pcmDataRight;
for ( unsigned int sample = 0; sample < frame->header.blocksize; sample++ )
{
pcmDataLeft.i = buffer[0][sample];
pcmDataRight.i = buffer[1][sample];
m_outBuffer.append( pcmDataLeft.b[0] );
m_outBuffer.append( pcmDataLeft.b[1] );
m_outBuffer.append( pcmDataRight.b[0] );
m_outBuffer.append( pcmDataRight.b[1] );
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
::FLAC__StreamDecoderSeekStatus
FLACTranscode::seek_callback(FLAC__uint64 absolute_byte_offset)
{
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
}
void
FLACTranscode::metadata_callback( const ::FLAC__StreamMetadata *metadata )
{
qDebug() << Q_FUNC_INFO << metadata->is_last;
switch ( metadata->type )
{
case FLAC__METADATA_TYPE_STREAMINFO:
{
FLAC::Metadata::StreamInfo stream_info( (::FLAC__StreamMetadata *)metadata, true );
// Try to determine samplerate
qDebug() << "FLACTranscode( BitsPerSample:" << stream_info.get_bits_per_sample() << "Samplerate:" << stream_info.get_sample_rate() << "Channels:" << stream_info.get_channels() << ")";
emit streamInitialized( stream_info.get_sample_rate(), stream_info.get_channels() );
m_FLACRunning = true;
break;
}
default:
qDebug() << "Not handling type:" << metadata->type;
break;
}
}
void
FLACTranscode::error_callback( ::FLAC__StreamDecoderErrorStatus status )
{
qDebug() << Q_FUNC_INFO << status;
}
bool
FLACTranscode::eof_callback()
{
return ( m_buffer.isEmpty() && m_finished );
}

View File

@@ -1,69 +0,0 @@
/*! \class FLACTranscode
\brief Transcoding plugin for FLAC streams.
*/
#ifndef FLAC_TRANSCODE_H
#define FLAC_TRANSCODE_H
#include "transcodeinterface.h"
#include <FLAC/format.h>
#include <FLAC++/decoder.h>
#include <FLAC++/metadata.h>
#include <QObject>
#include <QMutex>
#include <QDebug>
#include "dllmacro.h"
#define FLAC_BUFFER 32768 * 36
#define FLAC_BUFFER_PREFERRED 32768
class DLLEXPORT FLACTranscode : public TranscodeInterface , protected FLAC::Decoder::Stream
{
Q_OBJECT
public:
FLACTranscode();
~FLACTranscode();
const QStringList supportedTypes() const { QStringList l; l << "audio/flac" << "flac"; return l; }
int needData() { return FLAC_BUFFER - m_buffer.count(); }
bool haveData() { return !m_outBuffer.isEmpty(); }
unsigned int preferredDataSize() { return FLAC_BUFFER_PREFERRED; }
QByteArray data() { QByteArray b = m_outBuffer; m_outBuffer.clear(); return b; }
QMutex* mutex() { return &m_mutex; }
QByteArray* buffer() { return &m_buffer; }
signals:
void streamInitialized( long sampleRate, int channels );
public slots:
void onSeek( int seconds );
void clearBuffers();
void processData( const QByteArray& data, bool finish );
protected:
virtual ::FLAC__StreamDecoderReadStatus read_callback( FLAC__byte buffer[], size_t *bytes );
virtual ::FLAC__StreamDecoderWriteStatus write_callback( const ::FLAC__Frame *frame, const FLAC__int32 *const buffer[] );
virtual ::FLAC__StreamDecoderSeekStatus seek_callback( FLAC__uint64 absolute_byte_offset );
virtual bool eof_callback();
virtual void metadata_callback( const ::FLAC__StreamMetadata *metadata );
void error_callback( ::FLAC__StreamDecoderErrorStatus status );
private:
QByteArray m_outBuffer;
QMutex m_mutex;
QByteArray m_buffer;
bool m_FLACRunning;
bool m_finished;
};
#endif

View File

@@ -1,204 +0,0 @@
#include "madtranscode.h"
#include <QDebug>
typedef struct audio_dither
{
mad_fixed_t error[3];
mad_fixed_t random;
} audio_dither;
/* fast 32-bit pseudo-random number generator */
/* code from madplay */
static inline unsigned long prng( unsigned long state )
{
return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
}
/* dithers 24-bit output to 16 bits instead of simple rounding */
/* code from madplay */
static inline signed int dither( mad_fixed_t sample, audio_dither *dither )
{
unsigned int scalebits;
mad_fixed_t output, mask, random;
enum
{
MIN = -MAD_F_ONE,
MAX = MAD_F_ONE - 1
};
/* noise shape */
sample += dither->error[0] - dither->error[1] + dither->error[2];
dither->error[2] = dither->error[1];
dither->error[1] = dither->error[0] / 2;
/* bias */
output = sample + (1L << (MAD_F_FRACBITS + 1 - 16 - 1));
scalebits = MAD_F_FRACBITS + 1 - 16;
mask = (1L << scalebits) - 1;
/* dither */
random = prng(dither->random);
output += (random & mask) - (dither->random & mask);
dither->random = random;
/* clip */
/* TODO: better clipping function */
if (sample >= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample < -MAD_F_ONE)
sample = -MAD_F_ONE;
if (output >= MAD_F_ONE)
output = MAD_F_ONE - 1;
else if (output < -MAD_F_ONE)
output = -MAD_F_ONE;
/* quantize */
output &= ~mask;
/* error feedback */
dither->error[0] = sample - output;
/* scale */
return output >> scalebits;
}
MADTranscode::MADTranscode() :
m_decodedBufferCapacity( 32 * 1024 ),
m_mpegInitialised( false )
{
qDebug() << "Initialising MAD Transcoding";
mad_stream_init( &stream );
mad_frame_init( &frame );
mad_synth_init( &synth );
timer = mad_timer_zero;
last_timer = mad_timer_zero;
}
MADTranscode::~MADTranscode()
{
qDebug() << Q_FUNC_INFO;
mad_synth_finish( &synth );
mad_frame_finish( &frame );
mad_stream_finish( &stream );
}
void
MADTranscode::processData( const QByteArray &buffer, bool finish )
{
static audio_dither left_dither, right_dither;
int err = 0;
m_encodedBuffer.append( buffer );
while ( err == 0 && ( m_encodedBuffer.count() >= MP3_BUFFER || finish ) )
{
mad_stream_buffer( &stream, (const unsigned char*)m_encodedBuffer.data(), m_encodedBuffer.count() );
err = mad_frame_decode( &frame, &stream );
if ( stream.next_frame != 0 )
{
size_t r = stream.next_frame - stream.buffer;
m_encodedBuffer.remove( 0, r );
}
if ( err )
{
// if ( stream.error != MAD_ERROR_LOSTSYNC )
// qDebug() << "libmad error:" << mad_stream_errorstr( &stream );
if ( !MAD_RECOVERABLE( stream.error ) )
return;
err = 0;
}
else
{
mad_timer_add( &timer, frame.header.duration );
mad_synth_frame( &synth, &frame );
if ( !m_mpegInitialised )
{
long sampleRate = synth.pcm.samplerate;
int channels = synth.pcm.channels;
qDebug() << "madTranscode( Samplerate:" << sampleRate << "- Channels:" << channels << ")";
m_mpegInitialised = true;
emit streamInitialized( sampleRate, channels > 0 ? channels : 2 );
}
for ( int i = 0; i < synth.pcm.length; i++ )
{
union PCMDATA
{
short i;
unsigned char b[2];
} pcmData;
pcmData.i = dither( synth.pcm.samples[0][i], &left_dither );
m_decodedBuffer.append( pcmData.b[0] );
m_decodedBuffer.append( pcmData.b[1] );
if ( synth.pcm.channels == 2 )
{
pcmData.i = dither( synth.pcm.samples[1][i], &right_dither );
m_decodedBuffer.append( pcmData.b[0] );
m_decodedBuffer.append( pcmData.b[1] );
}
}
if ( timer.seconds != last_timer.seconds )
emit timeChanged( timer.seconds );
last_timer = timer;
}
}
}
void
MADTranscode::onSeek( int seconds )
{
mad_timer_t t;
t.seconds = seconds;
t.fraction = 0;
timer = mad_timer_zero;
mad_timer_add( &timer, t );
m_encodedBuffer.clear();
m_decodedBuffer.clear();
}
void
MADTranscode::clearBuffers()
{
mad_synth_finish( &synth );
mad_frame_finish( &frame );
mad_stream_finish( &stream );
m_mpegInitialised = false;
timer = mad_timer_zero;
last_timer = mad_timer_zero;
m_encodedBuffer.clear();
m_decodedBuffer.clear();
mad_stream_init( &stream );
mad_frame_init( &frame );
mad_synth_init( &synth );
}

View File

@@ -1,65 +0,0 @@
/*! \class MadTranscode
\brief Transcoding plugin for MP3 streams, using libmad.
*/
#ifndef MADTRANSCODE_H
#define MADTRANSCODE_H
#include "transcodeinterface.h"
#include "mad.h"
#include <QStringList>
#include <QByteArray>
#include <QObject>
#include <QMutex>
#include "dllmacro.h"
#define MP3_BUFFER 32768
#define MP3_BUFFER_PREFERRED 32768
class DLLEXPORT MADTranscode : public TranscodeInterface
{
Q_OBJECT
public:
MADTranscode();
virtual ~MADTranscode();
const QStringList supportedTypes() const { QStringList l; l << "application/x-mp3" << "mp3"; return l; }
int needData() { return MP3_BUFFER - m_encodedBuffer.count(); }
bool haveData() { return !m_decodedBuffer.isEmpty(); }
unsigned int preferredDataSize() { return MP3_BUFFER_PREFERRED; }
QByteArray data() { QByteArray b = m_decodedBuffer; m_decodedBuffer.clear(); return b; }
virtual void setBufferCapacity( int bytes ) { m_decodedBufferCapacity = bytes; }
int bufferSize() { return m_decodedBuffer.size(); }
public slots:
virtual void clearBuffers();
virtual void onSeek( int seconds );
virtual void processData( const QByteArray& data, bool finish );
signals:
void streamInitialized( long sampleRate, int channels );
void timeChanged( int seconds );
private:
QByteArray m_encodedBuffer;
QByteArray m_decodedBuffer;
int m_decodedBufferCapacity;
bool m_mpegInitialised;
struct mad_decoder decoder;
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
mad_timer_t timer;
mad_timer_t last_timer;
};
#endif

View File

@@ -1,263 +0,0 @@
#include <QMutexLocker>
#include <QStringList>
#include <QMessageBox>
#include <QDebug>
#include "rtaudiooutput.h"
#define BUFFER_SIZE 512
int
audioCallback( void *outputBuffer, void *inputBuffer, unsigned int bufferSize, double streamTime, RtAudioStreamStatus status, void* data_src )
{
RTAudioOutput* parent = (RTAudioOutput*)data_src;
QMutexLocker locker( parent->mutex() );
char* buffer = (char*)outputBuffer;
if ( !buffer || bufferSize != BUFFER_SIZE )
return 0;
int bufs = bufferSize * 2 * parent->sourceChannels();
memset( buffer, 0, bufs );
if ( parent->buffer()->size() >= bufs && !parent->isPaused() )
{
// Apply volume scaling
for ( int i = 0; i < bufs / 2; i++ )
{
union PCMDATA
{
short i;
unsigned char b[2];
} pcmData;
pcmData.b[0] = parent->buffer()->at( i * 2 );
pcmData.b[1] = parent->buffer()->at( i * 2 + 1 );
float pcmValue = (float)pcmData.i * parent->volume();
pcmData.i = (short)pcmValue;
buffer[i * 2] = pcmData.b[0];
buffer[i * 2 + 1] = pcmData.b[1];
}
parent->m_pcmCounter += bufs;
parent->buffer()->remove( 0, bufs );
}
return 0;
}
RTAudioOutput::RTAudioOutput() :
m_pcmCounter( 0 ),
m_audio( new RtAudio() ),
m_bufferEmpty( true ),
m_volume( 0.75 ),
m_paused( false ),
m_playing( false ),
m_bps( -1 )
{
qDebug() << Q_FUNC_INFO << m_audio->getCurrentApi();
devices();
}
RTAudioOutput::~RTAudioOutput()
{
qDebug() << Q_FUNC_INFO;
stopPlayback();
}
QStringList
RTAudioOutput::soundSystems()
{
QStringList l;
#ifdef WIN32
l << "DirectSound";
#endif
#ifdef Q_WS_X11
l << "Alsa";
#endif
#ifdef Q_WS_MAC
l << "CoreAudio";
#endif
return l;
}
QStringList
RTAudioOutput::devices()
{
qDebug() << Q_FUNC_INFO;
QStringList l;
try
{
qDebug() << "Device nums:" << m_audio->getDeviceCount();
for ( unsigned int i = 0; i < m_audio->getDeviceCount(); i++ )
{
RtAudio::DeviceInfo info;
info = m_audio->getDeviceInfo( i );
qDebug() << "Device found:" << i << QString::fromStdString( info.name ) << info.outputChannels << info.duplexChannels << info.isDefaultOutput;
if ( info.outputChannels > 0 )
l << QString::fromStdString( info.name ); // FIXME make it utf8 compatible
}
}
catch ( RtError &error )
{
}
return l;
}
bool
RTAudioOutput::startPlayback()
{
qDebug () << Q_FUNC_INFO;
if ( m_audio->isStreamOpen() )
{
m_audio->startStream();
m_playing = true;
}
return m_audio->isStreamOpen();
}
void
RTAudioOutput::stopPlayback()
{
qDebug() << Q_FUNC_INFO;
QMutexLocker locker( &m_mutex );
delete m_audio; // FIXME
m_audio = new RtAudio();
m_buffer.clear();
m_paused = false;
m_playing = false;
m_bps = -1;
m_pcmCounter = 0;
}
void
RTAudioOutput::initAudio( long sampleRate, int channels )
{
qDebug() << Q_FUNC_INFO << sampleRate << channels;
QMutexLocker locker( &m_mutex );
try
{
delete m_audio;
m_audio = new RtAudio();
m_bps = sampleRate * channels * 2;
m_pcmCounter = 0;
RtAudio::StreamParameters parameters;
parameters.deviceId = m_audio->getDefaultOutputDevice();
parameters.nChannels = channels;
parameters.firstChannel = 0;
unsigned int bufferFrames = BUFFER_SIZE;
RtAudio::StreamOptions options;
options.numberOfBuffers = 32;
//options.flags = RTAUDIO_SCHEDULE_REALTIME;
m_sourceChannels = channels;
m_buffer.clear();
/* if ( m_audio->isStreamRunning() )
m_audio->abortStream();
if ( m_audio->isStreamOpen() )
m_audio->closeStream();*/
m_audio->openStream( &parameters, NULL, RTAUDIO_SINT16, sampleRate, &bufferFrames, &audioCallback, this, &options );
}
catch ( RtError &error )
{
qDebug() << "Starting stream failed. RtAudio error type: " << error.getType();
}
}
bool
RTAudioOutput::needData()
{
if ( m_buffer.isEmpty() && !m_bufferEmpty )
{
m_bufferEmpty = true;
emit bufferEmpty();
}
return ( m_buffer.size() < 65535 ); // FIXME constant value
}
void
RTAudioOutput::processData( const QByteArray &buffer )
{
QMutexLocker locker( &m_mutex );
m_buffer.append( buffer );
if ( m_bufferEmpty && !buffer.isEmpty() )
{
m_bufferEmpty = false;
emit bufferFull();
}
}
void
RTAudioOutput::clearBuffers()
{
qDebug() << Q_FUNC_INFO;
QMutexLocker locker( &m_mutex );
m_buffer.clear();
m_bufferEmpty = true;
emit bufferEmpty();
}
int
RTAudioOutput::internalSoundCardID( int settingsID )
{
if ( settingsID < 0 )
settingsID = 0;
try
{
int card = 0;
for ( unsigned int i = 1; i <= m_audio->getDeviceCount(); i++ )
{
RtAudio::DeviceInfo info;
info = m_audio->getDeviceInfo( i );
if ( info.outputChannels > 0 )
{
if ( card++ == settingsID )
return i;
}
}
}
catch ( RtError &error )
{
}
#ifdef Q_WS_MAC
return 3; // FIXME?
#endif
return 1;
}

View File

@@ -1,71 +0,0 @@
#ifndef RTAUDIOPLAYBACK_H
#define RTAUDIOPLAYBACK_H
#include "RtAudio.h"
#include <QObject>
#include <QMutex>
class RTAudioOutput : public QObject
{
Q_OBJECT
public:
RTAudioOutput();
~RTAudioOutput();
void initAudio( long sampleRate, int channels );
float volume() { return m_volume; }
bool isPaused() { return m_paused; }
virtual bool isPlaying() { return m_playing; }
bool haveData() { return m_buffer.length() > 2048; }
bool needData();
void processData( const QByteArray &buffer );
QStringList soundSystems();
QStringList devices();
int sourceChannels() { return m_sourceChannels; }
QMutex* mutex() { return &m_mutex; }
QByteArray* buffer() { return &m_buffer; }
int m_pcmCounter;
public slots:
void clearBuffers();
bool startPlayback();
void stopPlayback();
void pause() { m_paused = true; }
void resume() { m_paused = false; }
void setVolume( int volume ) { m_volume = ((float)(volume)) / (float)100.0; emit volumeChanged( m_volume ); }
virtual void triggerTimers() { if ( m_bps > 0 ) emit timeElapsed( m_pcmCounter / m_bps ); else emit timeElapsed( 0 ); }
signals:
void bufferEmpty();
void bufferFull();
void volumeChanged( float volume );
void timeElapsed( unsigned int seconds );
private:
RtAudio *m_audio;
bool m_bufferEmpty;
float m_volume;
QByteArray m_buffer;
QMutex m_mutex;
int m_sourceChannels;
bool m_paused;
bool m_playing;
int m_bps;
int internalSoundCardID( int settingsID );
};
#endif

View File

@@ -1,36 +0,0 @@
#ifndef TRANSCODEINTERFACE_H
#define TRANSCODEINTERFACE_H
#include <QStringList>
#include <QByteArray>
#include <QObject>
#include <QMutex>
#include "dllmacro.h"
class DLLEXPORT TranscodeInterface : public QObject
{
Q_OBJECT
public:
virtual ~TranscodeInterface() {}
virtual const QStringList supportedTypes() const = 0;
virtual int needData() = 0;
virtual bool haveData() = 0;
virtual unsigned int preferredDataSize() = 0;
virtual QByteArray data() = 0;
// virtual void setBufferCapacity( int bytes ) = 0;
// virtual int bufferSize() = 0;
public slots:
virtual void clearBuffers() = 0;
virtual void onSeek( int seconds ) = 0;
virtual void processData( const QByteArray& data, bool finish ) = 0;
};
#endif

View File

@@ -1,120 +0,0 @@
#include "vorbistranscode.h"
size_t
vorbis_read( void* data_ptr, size_t byteSize, size_t sizeToRead, void* data_src )
{
VorbisTranscode* parent = (VorbisTranscode*)data_src;
QMutexLocker locker( parent->mutex() );
int r = byteSize * sizeToRead;
if ( r > parent->buffer()->size() )
r = parent->buffer()->size();
memcpy( data_ptr, (char*)parent->buffer()->data(), r );
parent->buffer()->remove( 0, r );
return r;
}
int
vorbis_seek( void* data_src, ogg_int64_t offset, int origin )
{
return -1;
}
int
vorbis_close( void* data_src )
{
// done ;-)
return 0;
}
long
vorbis_tell( void* data_src )
{
return -1;
}
VorbisTranscode::VorbisTranscode()
: m_vorbisInit( false )
{
qDebug() << Q_FUNC_INFO;
}
VorbisTranscode::~VorbisTranscode()
{
qDebug() << Q_FUNC_INFO;
}
void
VorbisTranscode::onSeek( int seconds )
{
QMutexLocker locker( &m_mutex );
m_buffer.clear();
m_outBuffer.clear();
}
void
VorbisTranscode::clearBuffers()
{
QMutexLocker locker( &m_mutex );
m_vorbisInit = false;
m_buffer.clear();
m_outBuffer.clear();
}
void
VorbisTranscode::processData( const QByteArray& data, bool )
{
m_mutex.lock();
m_buffer.append( data );
m_mutex.unlock();
if ( !m_vorbisInit && m_buffer.size() >= OGG_BUFFER )
{
ov_callbacks oggCallbacks;
oggCallbacks.read_func = vorbis_read;
oggCallbacks.close_func = vorbis_close;
oggCallbacks.seek_func = vorbis_seek;
oggCallbacks.tell_func = vorbis_tell;
ov_open_callbacks( this, &m_vorbisFile, 0, 0, oggCallbacks );
m_vorbisInit = true;
// Try to determine samplerate
vorbis_info* vi = ov_info( &m_vorbisFile, -1 );
qDebug() << "vorbisTranscode( Samplerate:" << vi->rate << "Channels:" << vi->channels << ")";
emit streamInitialized( vi->rate, vi->channels );
}
long result = 1;
int currentSection = 0;
while ( m_buffer.size() >= OGG_BUFFER && result > 0 )
{
char tempBuffer[16384];
result = ov_read( &m_vorbisFile, tempBuffer, sizeof( tempBuffer ), 0, 2, 1, &currentSection );
if ( result > 0 )
{
for ( int i = 0; i < ( result / 2 ); i++ )
{
m_outBuffer.append( tempBuffer[i * 2] );
m_outBuffer.append( tempBuffer[i * 2 + 1] );
}
}
}
}

View File

@@ -1,63 +0,0 @@
/*! \class VorbisTranscode
\brief Transcoding plugin for OGG/Vorbis streams.
*/
#ifndef VORBIS_TRANSCODE_H
#define VORBIS_TRANSCODE_H
#include "transcodeinterface.h"
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include <QObject>
#include <QMutex>
#include <QDebug>
#include <QStringList>
#include "dllmacro.h"
// Must not be smaller than 8500 bytes!
#define OGG_BUFFER 8500
#define OGG_BUFFER_PREFERRED 32768
class DLLEXPORT VorbisTranscode : public TranscodeInterface
{
Q_OBJECT
public:
VorbisTranscode();
~VorbisTranscode();
const QStringList supportedTypes() const { QStringList l; l << "application/ogg" << "ogg"; return l; }
int needData() { return OGG_BUFFER - m_buffer.count(); }
bool haveData() { return !m_outBuffer.isEmpty(); }
unsigned int preferredDataSize() { return OGG_BUFFER_PREFERRED; }
QByteArray data() { QByteArray b = m_outBuffer; m_outBuffer.clear(); return b; }
QMutex* mutex() { return &m_mutex; }
QByteArray* buffer() { return &m_buffer; }
public slots:
void clearBuffers();
void onSeek( int seconds );
void processData( const QByteArray& data, bool finish );
signals:
void streamInitialized( long sampleRate, int channels );
void timeChanged( int seconds );
private:
QByteArray m_outBuffer;
QMutex m_mutex;
QByteArray m_buffer;
OggVorbis_File m_vorbisFile;
bool m_vorbisInit;
};
#endif