kaudioconverter.cc

00001     /*
00002 
00003     Copyright (C) 2002 Nikolas Zimmermann <wildfox@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009   
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 
00020     */
00021 
00022 #include "config.h"
00023 #include "artskde.h"
00024 #include "connect.h"
00025 #include "flowsystem.h"
00026 #include "audiosubsys.h"
00027 #include "dynamicrequest.h"
00028 #include "kdatarequest_impl.h"
00029 #include "kioinputstream_impl.h"
00030 #include "kaudioconverter.moc"
00031 
00032 #include <iostream>
00033 
00034 #include <qfile.h>
00035 #include <qtimer.h>
00036 
00037 #include <kurl.h>
00038 #include <kdebug.h>
00039 #include <kmimetype.h>
00040 #include <kapplication.h>
00041 
00042 using namespace std;
00043 
00044 KAudioConverter::KAudioConverter()
00045 {
00046     m_incoming = 0;
00047     m_started = false;
00048 }
00049 
00050 KAudioConverter::~KAudioConverter()
00051 {
00052     delete m_incoming;
00053 }
00054 
00055 bool KAudioConverter::setup(int samplingRate)
00056 {
00057     string backupAudioIO = Arts::AudioSubSystem::the()->audioIO();
00058     int backupSamplingRate = Arts::AudioSubSystem::the()->samplingRate();
00059     
00060     Arts::AudioSubSystem::the()->audioIO("null");
00061     Arts::AudioSubSystem::the()->samplingRate(samplingRate);
00062     
00063     if(!Arts::AudioSubSystem::the()->open())
00064     {
00065         Arts::AudioSubSystem::the()->audioIO(backupAudioIO);
00066         Arts::AudioSubSystem::the()->samplingRate(backupSamplingRate);
00067         
00068         return false;
00069     }
00070 
00071     return true;
00072 }
00073 
00074 void KAudioConverter::slotMimeType(const QString &mimeType)
00075 {
00076     m_mimeType = mimeType;
00077     kapp->exit_loop();
00078 }
00079 
00080 void KAudioConverter::requestPlayObject(const KURL &url)
00081 {   
00082     string queryInterface = "Arts::PlayObject";
00083     
00084     Arts::KIOInputStream inputStream;
00085     
00086     if(!url.isLocalFile())
00087     {
00088         Arts::KIOInputStream_impl *inputStreamImpl = new Arts::KIOInputStream_impl();
00089         inputStream = Arts::KIOInputStream::_from_base(inputStreamImpl);
00090 
00091         QObject::connect(inputStreamImpl, SIGNAL(mimeTypeFound(const QString &)), SLOT(slotMimeType(const QString &)));
00092 
00093         inputStream.openURL(url.url().latin1());
00094         inputStream.streamStart();
00095 
00096         // ugly hacks.. :/
00097         kapp->enter_loop();
00098 
00099         queryInterface = "Arts::StreamPlayObject";      
00100     }
00101     else
00102     {
00103         KMimeType::Ptr mimetype = KMimeType::findByURL(url);
00104         m_mimeType = mimetype->name();
00105     }
00106     
00107     Arts::TraderQuery query;
00108     query.supports("Interface", queryInterface);
00109     query.supports("MimeType", string(m_mimeType.latin1()));
00110 
00111     string objectType;
00112 
00113     vector<Arts::TraderOffer> *offers = query.query();
00114     if(!offers->empty())
00115         objectType = offers->front().interfaceName(); // first offer
00116 
00117     delete offers;
00118 
00119     if(objectType.empty())
00120     {
00121         m_incoming = 0;
00122         return;
00123     }
00124 
00125     if(!url.isLocalFile())
00126     {
00127         Arts::StreamPlayObject result = Arts::SubClass(objectType);
00128         result.streamMedia(inputStream);
00129         result._node()->start();
00130 
00131         m_incoming = new KPlayObject(result, true);
00132     }
00133     else
00134     {
00135         Arts::PlayObject result = Arts::SubClass(objectType);
00136 
00137         if(result.loadMedia(string(QFile::encodeName(url.path()))))
00138         {
00139             result._node()->start();
00140             m_incoming = new KPlayObject(result, false);
00141         }
00142         else
00143             m_incoming = 0;
00144     }
00145 }
00146 
00147 void KAudioConverter::start()
00148 {
00149     if(m_started || !m_incoming)
00150         return;
00151 
00152     m_started = true;
00153     
00154     emit rawStreamStart();
00155 
00156     m_incoming->play();
00157 
00158     Arts::KDataRequest_impl *requestImpl = new Arts::KDataRequest_impl();
00159     m_request = Arts::KDataRequest::_from_base(requestImpl);
00160 
00161     Arts::connect(m_incoming->object(), "left", m_request, "left");
00162     Arts::connect(m_incoming->object(), "right", m_request, "right");
00163 
00164     QObject::connect(requestImpl, SIGNAL(newBlockSize(long)), SIGNAL(newBlockSize(long)));
00165     QObject::connect(requestImpl, SIGNAL(newBlockPointer(long)), SIGNAL(newBlockPointer(long)));
00166     QObject::connect(requestImpl, SIGNAL(newData()), SIGNAL(newData()));
00167 
00168     // Special mpeglib case
00169     // TODO: needed at all??
00170     usleep(100000);
00171     if(m_incoming->object()._base()->_isCompatibleWith("DecoderBaseObject"))
00172         if(!Arts::DynamicRequest(m_incoming->object()).method("_set_blocking").param(true).invoke())
00173             cerr << "mpeglib, and blocking attribute can't be changed?" << endl;
00174     
00175     m_request.start();
00176         
00177     // TODO: Maybe do this async, using QTimer::singleShot
00178     // But jowenn i think jowenn is right -> this would
00179     // lead to problems in slotNewData() when accessing the data
00180     // (could already be overwritten...)
00181     while(m_incoming->state() != Arts::posIdle)
00182         m_request.goOn();
00183         
00184     stop();
00185 }
00186 
00187 void KAudioConverter::stop()
00188 {
00189     if(!m_started || !m_incoming)
00190         return;
00191 
00192     m_incoming->halt();
00193     m_request.streamEnd();
00194 
00195     m_started = false;
00196 
00197     emit rawStreamFinished();
00198 }
KDE Home | KDE Accessibility Home | Description of Access Keys