defuze.me  Client
audiocore.cpp
00001 /**************************************************************************
00002 ** defuze.me Epitech Innovative Project
00003 **
00004 ** Copyright 2010-2011
00005 **   Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard
00006 **   Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier
00007 **
00008 ** All rights reserved.
00009 **************************************************************************/
00010 
00011 #include <QDebug>
00012 #include <QVariant>
00013 #include <QMap>
00014 #include "audiocore.hpp"
00015 #include "ffmpeg.hpp"
00016 #include "audiodecoder.hpp"
00017 #include "audiooutputdevice.hpp"
00018 #include "audiomixer.hpp"
00019 #include "exception.hpp"
00020 #include "audioeffectvolume.hpp"
00021 
00022 using namespace Audio;
00023 
00024 AudioCore::AudioCore(QStringList &)
00025 {
00026     nbOutput = 0;
00027     nbMixer = 0;
00028     nbDecoder = 0;
00029     stopThread = false;
00030     masterMixer = 0;
00031     crossfading = false;
00032 }
00033 
00034 AudioCore::~AudioCore()
00035 {
00036     wait(1000);
00037 }
00038 
00039 void    AudioCore::init(Cores *cores)
00040 {
00041     initCodecs();
00042     _cores = cores;
00043     start();
00044     QList<QAudioDeviceInfo> l = availableDevices(QAudio::AudioOutput);
00045     foreach(QAudioDeviceInfo i, l)
00046     {
00047         qDebug() << "Availble device: " << i.deviceName();
00048     }
00049     qDebug() << "Default device: " << QAudioDeviceInfo::defaultOutputDevice().deviceName();
00050 }
00051 
00052 
00053 void    AudioCore::aboutToQuit()
00054 {
00055     stopThread = true;
00056 }
00057 
00058 QList<QAudioDeviceInfo> AudioCore::availableDevices(QAudio::Mode mode = QAudio::AudioOutput) const
00059 {
00060     return QAudioDeviceInfo::availableDevices(mode);
00061 }
00062 
00063 void    AudioCore::initCodecs()
00064 {
00065     avcodec_init();
00066     avcodec_register_all();
00067     av_register_all();
00068 
00069     qDebug() << "AVCodec version: " << avformat_version();
00070     qDebug() << "AVFormat configuration:" << avformat_configuration();
00071 }
00072 
00073 
00074 
00075 AudioDecoder*   AudioCore::newAudioDecoder(QString playerName)
00076 {
00077     nbDecoder++;
00078     QString name = playerName + QString("_DECODER_") + QVariant(nbDecoder).toString();
00079     AudioDecoder *decoder = new AudioDecoder(name, this);
00080     audioDecoders.insert(name, decoder);
00081     return decoder;
00082 }
00083 
00084 AudioMixer*     AudioCore::newAudioMixer(const QString& name, AudioIO *input)
00085 {
00086     nbMixer++;
00087     QString _name = name;
00088     if (_name.isEmpty())
00089         _name = QString("MIXER_") + QVariant(nbMixer).toString();
00090     AudioMixer *mixer = new AudioMixer(_name, input);
00091     audioMixers.insert(_name, mixer);
00092     audioMixersList.push_front(mixer);
00093     return mixer;
00094 }
00095 
00096 AudioOutputDevice*  AudioCore::newAudioDevice(QAudioDeviceInfo device)
00097 {
00098     nbOutput++;
00099     QString name = QString("OUTPUT_") + QVariant(nbOutput).toString();
00100     AudioOutputDevice *output = new AudioOutputDevice(name, device);
00101 //  audioOutputDevices.insert(name, output);
00102     output->setParent(this);
00103     return output;
00104 }
00105 
00106 //AudioOutputDevice*    AudioCore::getAudioOutputDevice(QString name)
00107 //{
00108 //  return audioOutputDevices.value(name);
00109 //}
00110 
00111 QString AudioCore::formatSeconds(int seconds)
00112 {
00113     int mins = seconds / 60;
00114     int secs = seconds % 60;
00115 
00116     return QString("%1:%2").arg(mins, 2, 10, QChar('0')).arg(secs, 2, 10, QChar('0'));
00117 }
00118 
00119 void    AudioCore::run()
00120 {
00121     while(!stopThread)
00122     {
00123         try {
00124             foreach(AudioDecoder *decoder, audioDecoders)
00125             {
00126                 if (!stopThread && decoder->state() == AudioDecoder::Decoding)
00127                 {
00128                     decoder->run();
00129                 }
00130             }
00131             if (crossfading)
00132             {
00133                 qint64  length = crossfadeStart.msecsTo(QDateTime::currentDateTimeUtc());
00134                 float   cross = length / 5000.0;
00135 
00136                 if (cross >= 1)
00137                 {
00138                     crossfading = false;
00139                     emit crossfadeFinished();
00140                 }
00141                 else
00142                 {
00143                     static_cast<AudioEffectVolume*>(crossfadeFrom->getEffects()["Volume"])->setVolume(crossfadeFromVolume - cross*crossfadeFromVolume);
00144                     static_cast<AudioEffectVolume*>(crossfadeTo->getEffects()["Volume"])->setVolume(cross * crossfadeToVolume);
00145                 }
00146             }
00147             usleep(100);
00148         } catch (Exception& e) {
00149             forward(e);     // Send the exception to main thread and continue executing
00150             usleep(1000000);
00151         }
00152     }
00153 }
00154 
00155 void            AudioCore::startCrossfade(AudioMixer* from, AudioMixer* to)
00156 {
00157     crossfadeFrom = from;
00158     crossfadeTo = to;
00159     crossfadeFromVolume = static_cast<AudioEffectVolume*>(crossfadeFrom->getEffects()["Volume"])->volume();
00160     crossfadeToVolume = static_cast<AudioEffectVolume*>(crossfadeTo->getEffects()["Volume"])->volume();
00161     crossfadeStart = QDateTime::currentDateTimeUtc();
00162     crossfading = true;
00163 }
00164 
00165 void            AudioCore::stopCrossfade()
00166 {
00167     crossfading = false;
00168     static_cast<AudioEffectVolume*>(crossfadeFrom->getEffects()["Volume"])->setVolume(crossfadeFromVolume);
00169     static_cast<AudioEffectVolume*>(crossfadeTo->getEffects()["Volume"])->setVolume(crossfadeToVolume);
00170 }
00171 
00172 
00173 AudioMixer*     AudioCore::getMasterMixer()
00174 {
00175     return masterMixer;
00176 }
00177 
00178 QList<AudioMixer*>& AudioCore::getMixers()
00179 {
00180     return audioMixersList;
00181 }