mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 19:02:48 +00:00
328 lines
8.3 KiB
C++
328 lines
8.3 KiB
C++
![]() |
/*
|
||
|
* KCompactDisc - A CD drive interface for the KDE Project.
|
||
|
*
|
||
|
* Copyright (C) 2007 Alexander Kern <alex.kern@gmx.de>
|
||
|
*
|
||
|
* 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, or (at your option)
|
||
|
* any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "wmlib_interface.h"
|
||
|
|
||
|
#include <kdebug.h>
|
||
|
#include <klocale.h>
|
||
|
|
||
|
extern "C"
|
||
|
{
|
||
|
// We don't have libWorkMan installed already, so get everything
|
||
|
// from within our own directory
|
||
|
#include "wmlib/include/wm_cdrom.h"
|
||
|
#include "wmlib/include/wm_cdtext.h"
|
||
|
#include "wmlib/include/wm_helpers.h"
|
||
|
}
|
||
|
|
||
|
#define TRACK_VALID(track) ((track) && (track <= m_tracks))
|
||
|
|
||
|
KWMLibCompactDiscPrivate::KWMLibCompactDiscPrivate(KCompactDisc *p,
|
||
|
const QString &dev, const QString &audioSystem, const QString &audioDevice) :
|
||
|
KCompactDiscPrivate(p, dev),
|
||
|
m_handle(NULL),
|
||
|
m_audioSystem(audioSystem),
|
||
|
m_audioDevice(audioDevice)
|
||
|
{
|
||
|
m_interface = m_audioSystem;
|
||
|
}
|
||
|
|
||
|
KWMLibCompactDiscPrivate::~KWMLibCompactDiscPrivate()
|
||
|
{
|
||
|
if (m_handle) {
|
||
|
wm_cd_destroy(m_handle);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool KWMLibCompactDiscPrivate::createInterface()
|
||
|
{
|
||
|
QString devicePath;
|
||
|
|
||
|
devicePath = KCompactDisc::cdromDeviceUrl(m_deviceName).path();
|
||
|
|
||
|
// Debug.
|
||
|
//wm_cd_set_verbosity(WM_MSG_LEVEL_DEBUG | WM_MSG_CLASS_ALL);
|
||
|
|
||
|
int status = wm_cd_init(
|
||
|
devicePath.toAscii().data(),
|
||
|
m_audioSystem.toAscii().data(),
|
||
|
m_audioDevice.toAscii().data(),
|
||
|
NULL,
|
||
|
&m_handle);
|
||
|
|
||
|
if(!WM_CDS_ERROR(status)) {
|
||
|
m_deviceVendor = QLatin1String(wm_drive_vendor(m_handle));
|
||
|
m_deviceModel = QLatin1String(wm_drive_model(m_handle));
|
||
|
m_deviceRevision = QLatin1String(wm_drive_revision(m_handle));
|
||
|
|
||
|
Q_Q(KCompactDisc);
|
||
|
emit q->discChanged(0);
|
||
|
|
||
|
if (m_infoMode == KCompactDisc::Asynchronous) {
|
||
|
timerExpired();
|
||
|
} else {
|
||
|
QTimer::singleShot(1000, this, SLOT(timerExpired()));
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
m_handle = NULL;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
unsigned KWMLibCompactDiscPrivate::trackLength(unsigned track)
|
||
|
{
|
||
|
return (unsigned)wm_cd_gettracklen(m_handle, track);
|
||
|
}
|
||
|
|
||
|
bool KWMLibCompactDiscPrivate::isTrackAudio(unsigned track)
|
||
|
{
|
||
|
return !wm_cd_gettrackdata(m_handle, track);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::playTrackPosition(unsigned track, unsigned position)
|
||
|
{
|
||
|
unsigned firstTrack, lastTrack;
|
||
|
|
||
|
firstTrack = TRACK_VALID(track) ? track : 1;
|
||
|
lastTrack = firstTrack + 1;
|
||
|
lastTrack = TRACK_VALID(lastTrack) ? lastTrack : WM_ENDTRACK;
|
||
|
|
||
|
kDebug() << "play track " << firstTrack << " position "
|
||
|
<< position << endl;
|
||
|
|
||
|
wm_cd_play(m_handle, firstTrack, position, lastTrack);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::pause()
|
||
|
{
|
||
|
wm_cd_pause(m_handle);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::stop()
|
||
|
{
|
||
|
wm_cd_stop(m_handle);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::eject()
|
||
|
{
|
||
|
wm_cd_eject(m_handle);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::closetray()
|
||
|
{
|
||
|
wm_cd_closetray(m_handle);
|
||
|
}
|
||
|
|
||
|
/* WM_VOLUME_MUTE ... WM_VOLUME_MAXIMAL */
|
||
|
/* WM_BALANCE_ALL_LEFTS .WM_BALANCE_SYMMETRED. WM_BALANCE_ALL_RIGHTS */
|
||
|
#define RANGE2PERCENT(x, min, max) (((x) - (min)) * 100)/ ((max) - (min))
|
||
|
#define PERCENT2RANGE(x, min, max) ((((x) * ((max) - (min))) / 100 ) + (min))
|
||
|
void KWMLibCompactDiscPrivate::setVolume(unsigned volume)
|
||
|
{
|
||
|
int vol, bal;
|
||
|
vol = PERCENT2RANGE(volume, WM_VOLUME_MUTE, WM_VOLUME_MAXIMAL);
|
||
|
bal = wm_cd_getbalance(m_handle);
|
||
|
wm_cd_volume(m_handle, vol, bal);
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::setBalance(unsigned balance)
|
||
|
{
|
||
|
int vol, bal;
|
||
|
vol = wm_cd_getvolume(m_handle);
|
||
|
bal = PERCENT2RANGE(balance, WM_BALANCE_ALL_LEFTS, WM_BALANCE_ALL_RIGHTS);
|
||
|
wm_cd_volume(m_handle, vol, bal);
|
||
|
}
|
||
|
|
||
|
unsigned KWMLibCompactDiscPrivate::volume()
|
||
|
{
|
||
|
int vol = wm_cd_getvolume(m_handle);
|
||
|
unsigned volume = RANGE2PERCENT(vol, WM_VOLUME_MUTE, WM_VOLUME_MAXIMAL);
|
||
|
return volume;
|
||
|
}
|
||
|
|
||
|
unsigned KWMLibCompactDiscPrivate::balance()
|
||
|
{
|
||
|
int bal = wm_cd_getbalance(m_handle);
|
||
|
unsigned balance = RANGE2PERCENT(bal, WM_BALANCE_ALL_LEFTS, WM_BALANCE_ALL_RIGHTS);
|
||
|
|
||
|
return balance;
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::queryMetadata()
|
||
|
{
|
||
|
cdtext();
|
||
|
//cddb();
|
||
|
}
|
||
|
|
||
|
KCompactDisc::DiscStatus KWMLibCompactDiscPrivate::discStatusTranslate(int status)
|
||
|
{
|
||
|
switch (status) {
|
||
|
case WM_CDM_TRACK_DONE:
|
||
|
case WM_CDM_PLAYING:
|
||
|
case WM_CDM_FORWARD:
|
||
|
return KCompactDisc::Playing;
|
||
|
case WM_CDM_PAUSED:
|
||
|
return KCompactDisc::Paused;
|
||
|
case WM_CDM_STOPPED:
|
||
|
return KCompactDisc::Stopped;
|
||
|
case WM_CDM_EJECTED:
|
||
|
return KCompactDisc::Ejected;
|
||
|
case WM_CDM_NO_DISC:
|
||
|
case WM_CDM_UNKNOWN:
|
||
|
return KCompactDisc::NoDisc;
|
||
|
case WM_CDM_CDDAERROR:
|
||
|
case WM_CDM_LOADING:
|
||
|
case WM_CDM_BUFFERING:
|
||
|
return KCompactDisc::NotReady;
|
||
|
default:
|
||
|
return KCompactDisc::Error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::timerExpired()
|
||
|
{
|
||
|
KCompactDisc::DiscStatus status;
|
||
|
unsigned track, i;
|
||
|
Q_Q(KCompactDisc);
|
||
|
|
||
|
status = discStatusTranslate(wm_cd_status(m_handle));
|
||
|
|
||
|
if(m_status != status) {
|
||
|
if(skipStatusChange(status))
|
||
|
goto timerExpiredExit;
|
||
|
|
||
|
m_status = status;
|
||
|
|
||
|
switch(m_status) {
|
||
|
case KCompactDisc::Ejected:
|
||
|
case KCompactDisc::NoDisc:
|
||
|
clearDiscInfo();
|
||
|
break;
|
||
|
default:
|
||
|
if(m_tracks == 0) {
|
||
|
m_tracks = wm_cd_getcountoftracks(m_handle);
|
||
|
if(m_tracks > 0) {
|
||
|
kDebug() << "New disc with " << m_tracks << " tracks";
|
||
|
m_discId = wm_cddb_discid(m_handle);
|
||
|
|
||
|
for(i = 1; i <= m_tracks; i++) {
|
||
|
m_trackStartFrames.append(wm_cd_gettrackstart(m_handle, i));
|
||
|
}
|
||
|
m_trackStartFrames.append(wm_cd_gettrackstart(m_handle, i));
|
||
|
|
||
|
m_discLength = FRAMES2SEC(m_trackStartFrames[m_tracks] -
|
||
|
m_trackStartFrames[0]);
|
||
|
|
||
|
make_playlist();
|
||
|
|
||
|
m_trackArtists.append(i18n("Unknown Artist"));
|
||
|
m_trackTitles.append(i18n("Unknown Title"));
|
||
|
for(i = 1; i <= m_tracks; i++) {
|
||
|
m_trackArtists.append(i18n("Unknown Artist"));
|
||
|
m_trackTitles.append(ki18n("Track %1").subs(i, 2).toString());
|
||
|
}
|
||
|
|
||
|
kDebug() << "m_tracks " << m_tracks;
|
||
|
kDebug() << "m_trackStartFrames " << m_trackStartFrames;
|
||
|
kDebug() << "m_trackArtists " << m_trackArtists;
|
||
|
kDebug() << "m_trackTitles " << m_trackTitles;
|
||
|
|
||
|
emit q->discChanged(m_tracks);
|
||
|
|
||
|
if(m_autoMetadata)
|
||
|
queryMetadata();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch(m_status) {
|
||
|
case KCompactDisc::Playing:
|
||
|
m_trackPosition = wm_get_cur_pos_rel(m_handle);
|
||
|
m_discPosition = wm_get_cur_pos_abs(m_handle) - FRAMES2SEC(m_trackStartFrames[0]);
|
||
|
// Update the current playing position.
|
||
|
if(m_seek) {
|
||
|
kDebug() << "seek: " << m_seek << " trackPosition " << m_trackPosition;
|
||
|
if(abs((long)(m_trackExpectedPosition - m_trackPosition)) > m_seek)
|
||
|
m_seek = 0;
|
||
|
else
|
||
|
m_seek = abs((long)(m_trackExpectedPosition - m_trackPosition));
|
||
|
}
|
||
|
|
||
|
if(!m_seek) {
|
||
|
emit q->playoutPositionChanged(m_trackPosition);
|
||
|
//emit q->playoutDiscPositionChanged(m_discPosition);
|
||
|
}
|
||
|
|
||
|
// Per-event processing.
|
||
|
track = wm_cd_getcurtrack(m_handle);
|
||
|
|
||
|
if(m_track != track) {
|
||
|
m_track = track;
|
||
|
emit q->playoutTrackChanged(m_track);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case KCompactDisc::Stopped:
|
||
|
m_seek = 0;
|
||
|
m_track = 0;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
timerExpiredExit:
|
||
|
// Now that we have incurred any delays caused by the signals, we'll start the timer.
|
||
|
QTimer::singleShot(1000, this, SLOT(timerExpired()));
|
||
|
}
|
||
|
|
||
|
void KWMLibCompactDiscPrivate::cdtext()
|
||
|
{
|
||
|
struct cdtext_info *info;
|
||
|
unsigned i;
|
||
|
Q_Q(KCompactDisc);
|
||
|
|
||
|
info = wm_cd_get_cdtext(m_handle);
|
||
|
|
||
|
if(!info || !info->valid || (unsigned)info->count_of_entries != (m_tracks + 1)) {
|
||
|
kDebug() << "no or invalid CDTEXT";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_trackArtists[0] = QLatin1String( reinterpret_cast<char*>(info->blocks[0]->performer[0]) );
|
||
|
m_trackTitles[0] = QLatin1String( reinterpret_cast<char*>(info->blocks[0]->name[0]) );
|
||
|
|
||
|
for(i = 1; i <= m_tracks; i++) {
|
||
|
m_trackArtists[i] = QLatin1String( reinterpret_cast<char*>(info->blocks[0]->performer[i]) );
|
||
|
m_trackTitles[i] =QLatin1String( reinterpret_cast<char*>(info->blocks[0]->name[i]) );
|
||
|
}
|
||
|
|
||
|
kDebug() << "CDTEXT";
|
||
|
kDebug() << "m_trackArtists " << m_trackArtists;
|
||
|
kDebug() << "m_trackTitles " << m_trackTitles;
|
||
|
|
||
|
emit q->discInformation(KCompactDisc::Cdtext);
|
||
|
}
|
||
|
|
||
|
#include "moc_wmlib_interface.cpp"
|