|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2005 Max Howell <max.howell@methylblue.com> *
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include <akode-engine.h>
|
|
|
|
#include <akode/decoder.h>
|
|
|
|
#include <akode/player.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
|
|
|
|
AMAROK_EXPORT_PLUGIN( AkodeEngine )
|
|
|
|
|
|
|
|
|
|
|
|
namespace Amarok
|
|
|
|
{
|
|
|
|
class Manager : public aKode::Player::Manager
|
|
|
|
{
|
|
|
|
AkodeEngine *m_engine;
|
|
|
|
|
|
|
|
/// Called for all stateChanges
|
|
|
|
virtual void stateChangeEvent( aKode::Player::State )
|
|
|
|
{
|
|
|
|
TQApplication::postEvent( m_engine, new TQCustomEvent( 3000 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Called when a decoder reaches end of file
|
|
|
|
virtual void eofEvent()
|
|
|
|
{
|
|
|
|
TQApplication::postEvent( m_engine, new TQCustomEvent( 3001 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Called when a decoder encounters a fatal error
|
|
|
|
virtual void errorEvent()
|
|
|
|
{
|
|
|
|
TQApplication::postEvent( m_engine, new TQCustomEvent( 3002 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
Manager( AkodeEngine *engine ) : m_engine( engine ) {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AkodeEngine::AkodeEngine()
|
|
|
|
: m_player( 0 )
|
|
|
|
{}
|
|
|
|
|
|
|
|
AkodeEngine::~AkodeEngine()
|
|
|
|
{
|
|
|
|
if( m_player )
|
|
|
|
m_player->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
AkodeEngine::init()
|
|
|
|
{
|
|
|
|
// startTimer( 20 );
|
|
|
|
|
|
|
|
m_player = new aKode::Player();
|
|
|
|
m_player->setManager( new Amarok::Manager( this ) );
|
|
|
|
m_player->setMonitor( &m_scope );
|
|
|
|
|
|
|
|
return m_player->open( "auto" );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
AkodeEngine::load( const KURL &url, bool isStream )
|
|
|
|
{
|
|
|
|
Engine::Base::load( url, isStream );
|
|
|
|
|
|
|
|
return m_player->load( url.path().local8Bit().data() );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
AkodeEngine::play( uint /*offset*/ )
|
|
|
|
{
|
|
|
|
//FIXME this seemed to crash Amarok
|
|
|
|
//m_player->decoder()->seek( offset );
|
|
|
|
m_player->play();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AkodeEngine::unpause()
|
|
|
|
{
|
|
|
|
m_player->play();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
AkodeEngine::canDecode( const KURL &url ) const
|
|
|
|
{
|
|
|
|
const TQString ext = url.path().right( 4 ).lower();
|
|
|
|
|
|
|
|
return ext == ".mp3" || ext == ".ogg" || ext == ".wav" || ext ==".mpc" || ext == "flac";
|
|
|
|
}
|
|
|
|
|
|
|
|
uint
|
|
|
|
AkodeEngine::position() const
|
|
|
|
{
|
|
|
|
if( !m_player->decoder() )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const int pos = m_player->decoder()->position();
|
|
|
|
|
|
|
|
return pos >= 0 ? pos : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AkodeEngine::stop()
|
|
|
|
{
|
|
|
|
m_player->stop();
|
|
|
|
m_player->unload();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AkodeEngine::pause()
|
|
|
|
{
|
|
|
|
switch( m_player->state() ) {
|
|
|
|
case aKode::Player::Playing: m_player->pause(); break;
|
|
|
|
case aKode::Player::Paused: m_player->play(); break;
|
|
|
|
default: ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AkodeEngine::setVolumeSW( uint v )
|
|
|
|
{
|
|
|
|
m_player->setVolume( (float)v / 100.0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AkodeEngine::seek( uint ms )
|
|
|
|
{
|
|
|
|
m_player->decoder()->seek( ms );
|
|
|
|
}
|
|
|
|
|
|
|
|
Engine::State
|
|
|
|
AkodeEngine::state() const
|
|
|
|
{
|
|
|
|
switch( m_player->state() )
|
|
|
|
{
|
|
|
|
case aKode::Player::Open:
|
|
|
|
case aKode::Player::Closed: return Engine::Empty;
|
|
|
|
default:
|
|
|
|
case aKode::Player::Loaded: return Engine::Idle;
|
|
|
|
case aKode::Player::Playing: return Engine::Playing;
|
|
|
|
case aKode::Player::Paused: return Engine::Paused;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
AkodeEngine::event( TQEvent *e )
|
|
|
|
{
|
|
|
|
switch( e->type() )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
case TQEvent::Timer:
|
|
|
|
if( m_player->decoder() && m_player->decoder()->eof() ) {
|
|
|
|
m_player->stop();
|
|
|
|
emit trackEnded();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
*/
|
|
|
|
case 3000:
|
|
|
|
emit stateChanged( state() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3001:
|
|
|
|
m_player->stop();
|
|
|
|
emit trackEnded();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3002:
|
|
|
|
m_player->stop();
|
|
|
|
emit trackEnded();
|
|
|
|
emit infoMessage( i18n("Unable to decode <i>%1</i>").arg( m_url.prettyURL()) );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Engine::Scope& AkodeEngine::scope()
|
|
|
|
{
|
|
|
|
return m_scope.scope();
|
|
|
|
}
|