Ticket #4222: 4222-v4.patch

File 4222-v4.patch, 112.7 KB (added by paulh, 12 years ago)

Updated patch

  • mythmusic/playbackbox.cpp

     
    2727#include "mainvisual.h"
    2828#include "smartplaylist.h"
    2929#include "search.h"
     30#include "musicplayer.h"
    3031
    3132PlaybackBoxMusic::PlaybackBoxMusic(MythMainWindow *parent, QString window_name,
    32                                    QString theme_filename,
    33                                    PlaylistsContainer *the_playlists,
    34                                    AllMusic *the_music,
    35                                    const QString &dev, const char *name)
     33                                   QString theme_filename, const QString &dev, const char *name)
    3634
    3735                : MythThemedDialog(parent, window_name, theme_filename, name)
    3836{
    3937    //  A few internal variable defaults
    40  
    41     input = NULL;
    42     output = NULL;
    43     decoder = NULL;
    4438    mainvisual = NULL;
    4539    visual_mode_timer = NULL;
    4640    lcd_update_timer = NULL;
    4741    waiting_for_playlists_timer = NULL;
    4842    speed_scroll_timer = NULL;
    49     playlist_tree = NULL;
    5043    playlist_popup = NULL;
    5144    progress = NULL;
    5245
    53     isplaying = false;
     46    gPlayer->setListener(this);
     47
    5448    tree_is_done = false;
    5549    first_playlist_check = true;
    5650    outputBufferSize = 256;
     
    7569    scan_for_cd = gContext->GetNumSetting("AutoPlayCD", 0);
    7670    m_CDdevice = dev;
    7771
    78     // Set our pointers the playlists and the metadata containers
    79 
    80     all_playlists = the_playlists;
    81     all_music = the_music;
    82 
    8372    // Get some user set options
    8473
    8574    show_whole_tree = gContext->GetNumSetting("ShowWholeTree", 1);
     
    112101                this, SLOT(hideVolume()));
    113102    }
    114103
    115     // Figure out the shuffle mode
     104    setShuffleMode(gPlayer->getShuffleMode());
    116105
    117     QString playmode = gContext->GetSetting("PlayMode", "none");
    118     if (playmode.lower() == "random")
    119         setShuffleMode(SHUFFLE_RANDOM);
    120     else if (playmode.lower() == "intelligent")
    121         setShuffleMode(SHUFFLE_INTELLIGENT);
    122     else if (playmode.lower() == "album")
    123         setShuffleMode(SHUFFLE_ALBUM);
    124     else if (playmode.lower() == "artist")
    125         setShuffleMode(SHUFFLE_ARTIST);
    126     else
    127         setShuffleMode(SHUFFLE_OFF);
     106    resumemode = gPlayer->getResumeMode();
    128107
    129     QString resumestring = gContext->GetSetting("ResumeMode", "off");
    130     if (resumestring.lower() == "off")
    131         resumemode = RESUME_OFF;
    132     else if (resumestring.lower() == "track")
    133         resumemode = RESUME_TRACK;
    134     else
    135         resumemode = RESUME_EXACT;
     108    setRepeatMode(gPlayer->getRepeatMode());
    136109
    137     QString repeatmode = gContext->GetSetting("RepeatMode", "all");
    138     if (repeatmode.lower() == "track")
    139         setRepeatMode(REPEAT_TRACK);
    140     else if (repeatmode.lower() == "all")
    141         setRepeatMode(REPEAT_ALL);
    142     else
    143         setRepeatMode(REPEAT_OFF);
    144 
    145110    // Set some button values
    146111
    147112    if (!keyboard_accelerators)
     
    170135        // Set please wait on the LCD
    171136        QPtrList<LCDTextItem> textItems;
    172137        textItems.setAutoDelete(true);
    173        
     138
    174139        textItems.append(new LCDTextItem(1, ALIGN_CENTERED, "Please Wait",
    175140                         "Generic"));
    176141        lcd->switchToGeneric(&textItems);
     
    196161        mainvisual->setGeometry(screenwidth + 10, screenheight + 10, 160, 160);
    197162    mainvisual->show();
    198163
     164    gPlayer->setVisual(mainvisual);
     165
    199166    fullscreen_blank = false;
    200167
    201168    visual_modes = QStringList::split(';', gContext->GetSetting("VisualMode"));
     
    238205
    239206PlaybackBoxMusic::~PlaybackBoxMusic(void)
    240207{
    241     savePosition(currentTime);
    242 
    243     stopAll();
    244 
    245     if (output)
    246     {
    247         delete output;
    248         output = NULL;
    249     }
    250 
    251208    if (progress)
    252209    {
    253210        progress->Close();
     
    262219        delete cd_reader_thread;
    263220    }
    264221
    265     if (playlist_tree)
    266         delete playlist_tree;
    267 
    268     if (shufflemode == SHUFFLE_INTELLIGENT)
     222    MusicPlayer::ShuffleMode shufflemode = gPlayer->getShuffleMode();
     223    if (shufflemode == MusicPlayer::SHUFFLE_INTELLIGENT)
    269224        gContext->SaveSetting("PlayMode", "intelligent");
    270     else if (shufflemode == SHUFFLE_RANDOM)
     225    else if (shufflemode == MusicPlayer::SHUFFLE_RANDOM)
    271226        gContext->SaveSetting("PlayMode", "random");
    272     else if (shufflemode == SHUFFLE_ALBUM)
     227    else if (shufflemode == MusicPlayer::SHUFFLE_ALBUM)
    273228        gContext->SaveSetting("PlayMode", "album");
    274     else if (shufflemode == SHUFFLE_ARTIST)
     229    else if (shufflemode == MusicPlayer::SHUFFLE_ARTIST)
    275230        gContext->SaveSetting("PlayMode", "artist");
    276231    else
    277232        gContext->SaveSetting("PlayMode", "none");
    278233
    279     if (repeatmode == REPEAT_TRACK)
     234    MusicPlayer::RepeatMode repeatmode = gPlayer->getRepeatMode();
     235    if (repeatmode == MusicPlayer::REPEAT_TRACK)
    280236        gContext->SaveSetting("RepeatMode", "track");
    281     else if (repeatmode == REPEAT_ALL)
     237    else if (repeatmode == MusicPlayer::REPEAT_ALL)
    282238        gContext->SaveSetting("RepeatMode", "all");
    283239    else
    284240        gContext->SaveSetting("RepeatMode", "none");
     241
    285242    if (class LCD *lcd = LCD::Get())
    286243        lcd->switchToTime();
     244
     245    gMusicData->all_music->save();
     246    gPlayer->refreshMetadata();
    287247}
    288248
    289249bool PlaybackBoxMusic::onMediaEvent(MythMediaDevice*)
     
    304264    resetTimer();
    305265
    306266    QStringList actions;
    307     gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions);
     267    gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions, false);
    308268
    309269    int scrollAmt = 1;
    310270
     
    343303        }
    344304        else if (action == "PAUSE")
    345305        {
    346             if (isplaying)
     306            if (gPlayer->isPlaying())
    347307            {
    348308                if (pause_button)
    349309                    pause_button->push();
     
    371331                stop_button->push();
    372332            else
    373333                stop();
    374 
    375334            currentTime = 0;
    376335        }
    377336        else if (action == "THMBUP")
     
    427386                bannerToggle(curMeta);
    428387            else
    429388                showEditMetadataDialog();
     389        else if (action == "ESCAPE" && visualizer_status != 2)
     390        {
     391            DialogBox *dialog = new DialogBox(gContext->GetMainWindow(),
     392                             tr("Exiting Music Player\n"
     393                             "Do you want to continue playing in the background?"));
     394            dialog->AddButton("No - Exit, Stop Playing");
     395            dialog->AddButton("Yes - Exit, Continue Playing");
     396            dialog->AddButton("Cancel");
     397            int res = dialog->exec();
     398            dialog->deleteLater();
     399
     400            if (res == kDialogCodeButton0)
     401            {
     402                gPlayer->savePosition();
     403                stopAll();
     404                done(kDialogCodeAccepted);
     405            }
     406            else if (res == kDialogCodeButton1)
     407            {
     408                gPlayer->setListener(NULL);
     409                gPlayer->setVisual(NULL);
     410                done(kDialogCodeAccepted);
     411            }
     412            else
     413                handled = true;
     414        }
    430415        else
    431416            handled = false;
    432417    }
     
    541526                music_tree_list->incSearchStart();
    542527            else if (action == "INCSEARCHNEXT")
    543528                music_tree_list->incSearchNext();
    544             else
    545                 handled = false;
    546529        }
    547530    }
    548531    else
     
    565548                handled = false;
    566549        }
    567550    }
    568 
    569     if (!handled)
    570         MythThemedDialog::keyPressEvent(e);
    571551}
    572552
    573553void PlaybackBoxMusic::handlePush(QString buttonname)
     
    673653        return;
    674654
    675655    // save all pending metadata to then DB so that the smart playlists can use it
    676     all_music->save();
     656    gMusicData->all_music->save();
    677657
    678658    closePlaylistPopup();
    679659
     
    800780    {
    801781        // update playlist from quick playlist
    802782        if (menufilters)
    803             all_playlists->getActive()->fillSonglistFromQuery(
     783            gMusicData->all_playlists->getActive()->fillSonglistFromQuery(
    804784                        whereClause, false, PL_FILTERONLY, curTrackID);
    805785        else
    806             all_playlists->getActive()->fillSonglistFromQuery(
     786            gMusicData->all_playlists->getActive()->fillSonglistFromQuery(
    807787                        whereClause, bRemoveDups, insertOption, curTrackID);
    808788    }
    809789    else
    810790    {
    811791        // update playlist from smart playlist
    812792        if (menufilters)
    813             all_playlists->getActive()->fillSonglistFromSmartPlaylist(
     793            gMusicData->all_playlists->getActive()->fillSonglistFromSmartPlaylist(
    814794                    curSmartPlaylistCategory, curSmartPlaylistName,
    815795                    false, PL_FILTERONLY, curTrackID);
    816796        else
    817797        {
    818             all_playlists->getActive()->fillSonglistFromSmartPlaylist(
     798            gMusicData->all_playlists->getActive()->fillSonglistFromSmartPlaylist(
    819799                    curSmartPlaylistCategory, curSmartPlaylistName,
    820800                    bRemoveDups, insertOption, curTrackID);
    821801        }
     
    909889{
    910890    if (!cd_reader_thread)
    911891    {
    912         cd_reader_thread = new ReadCDThread(m_CDdevice,
    913                                             all_playlists, all_music);
     892        cd_reader_thread = new ReadCDThread(m_CDdevice);
    914893        cd_reader_thread->start();
    915894    }
    916895
     
    949928    if (cd_reader_thread->getLock()->locked())
    950929        return;
    951930
    952     if (!scan_for_cd) {
     931    if (!scan_for_cd)
     932    {
    953933        cd_watcher->stop();
    954934        delete cd_watcher;
    955935        cd_watcher = NULL;
     
    961941
    962942    if (!scan_for_cd || cd_reader_thread->statusChanged())
    963943    {
    964         all_playlists->clearCDList();
    965         all_playlists->getActive()->ripOutAllCDTracksNow();
     944        gMusicData->all_playlists->clearCDList();
     945        gMusicData->all_playlists->getActive()->ripOutAllCDTracksNow();
    966946
    967         if (all_music->getCDTrackCount())
     947        if (gMusicData->all_music->getCDTrackCount())
    968948        {
    969949            visual_mode_timer->stop();
    970950
    971             all_playlists->getActive()->removeAllTracks();
    972             all_playlists->getActive()->fillSongsFromCD();
     951            gMusicData->all_playlists->getActive()->removeAllTracks();
     952            gMusicData->all_playlists->getActive()->fillSongsFromCD();
    973953
    974954        }
    975955
     
    995975    // store the current track metadata in case the track changes
    996976    // while we show the edit dialog
    997977    GenericTree *node = music_tree_list->getCurrentNode();
    998     Metadata *editMeta = all_music->getMetadata( node->getInt() );
     978    Metadata *editMeta = gMusicData->all_music->getMetadata( node->getInt() );
    999979
    1000980    EditMetadataDialog editDialog(editMeta, gContext->GetMainWindow(),
    1001981                      "edit_metadata", "music-", "edit metadata");
    1002982    if (kDialogCodeRejected != editDialog.exec())
    1003983    {
    1004984        // update the metadata copy stored in all_music
    1005         if (all_music->updateMetadata(editMeta->ID(), editMeta))
     985        if (gMusicData->all_music->updateMetadata(editMeta->ID(), editMeta))
    1006986        {
    1007987           // update the displayed track info
    1008988           if (node)
    1009989           {
    1010990               bool errorFlag;
    1011                node->setString(all_music->getLabel(editMeta->ID(), &errorFlag));
     991               node->setString(gMusicData->all_music->getLabel(editMeta->ID(), &errorFlag));
    1012992               music_tree_list->refresh();
    1013993
    1014994               // make sure the track hasn't changed
     
    10321012        branches_to_current_node = *a_route;
    10331013
    10341014        // reload music
    1035         all_music->save();
    1036         all_music->startLoading();
    1037         while (!all_music->doneLoading())
     1015        gMusicData->all_music->save();
     1016        gMusicData->all_music->startLoading();
     1017        while (!gMusicData->all_music->doneLoading())
    10381018        {
    10391019            qApp->processEvents();
    10401020            usleep(50000);
    10411021        }
    1042         all_playlists->postLoad();
     1022        gMusicData->all_playlists->postLoad();
    10431023
    10441024        constructPlaylistTree();
    10451025
     
    10601040        }
    10611041
    10621042        GenericTree *node = music_tree_list->getCurrentNode();
    1063         curMeta = all_music->getMetadata(node->getInt());
     1043        curMeta = gMusicData->all_music->getMetadata(node->getInt());
    10641044
    1065         setShuffleMode(shufflemode);
     1045        setShuffleMode(gPlayer->getShuffleMode());
    10661046
    10671047        music_tree_list->refresh();
    10681048
     
    10821062    }
    10831063    else
    10841064    {
    1085         if (all_playlists->doneLoading() &&
    1086             all_music->doneLoading())
     1065        if (gMusicData->all_playlists->doneLoading() &&
     1066            gMusicData->all_music->doneLoading())
    10871067        {
    10881068            if (progress)
    10891069            {
     
    11041084                branches_to_current_node.append(1); //  We're on a playlist (not "My Music")
    11051085                branches_to_current_node.append(0); //  Active play Queue
    11061086
    1107                 if (resumemode > RESUME_OFF)
    1108                     restorePosition();
     1087                if (gPlayer->isPlaying())
     1088                {
     1089                    restorePosition(gPlayer->getRouteToCurrent());
     1090                }
    11091091                else
    1110                     music_tree_list->moveToNodesFirstChild(branches_to_current_node);
     1092                {
     1093                    if (resumemode > MusicPlayer::RESUME_OFF)
     1094                        restorePosition(gContext->GetSetting("MusicBookmark", ""));
     1095                    else
     1096                        music_tree_list->moveToNodesFirstChild(branches_to_current_node);
     1097                }
    11111098
    11121099                music_tree_list->refresh();
    11131100                if (show_whole_tree)
     
    11291116        }
    11301117        else
    11311118        {
    1132             if (!all_music->doneLoading())
     1119            if (!gMusicData->all_music->doneLoading())
    11331120            {
    11341121                // Only bother with progress dialogue
    11351122                // if we have a reasonable number of tracks
    1136                 if (all_music->count() >= 250)
     1123                if (gMusicData->all_music->count() >= 250)
    11371124                {
    11381125                    if (!progress)
    11391126                    {
    11401127                        progress = new MythProgressDialog(
    1141                             QObject::tr("Loading Music"), all_music->count());
     1128                            QObject::tr("Loading Music"), gMusicData->all_music->count());
    11421129                        progress_type = kProgressMusic;
    11431130                    }
    1144                     progress->setProgress(all_music->countLoaded());
     1131                    progress->setProgress(gMusicData->all_music->countLoaded());
    11451132                }
    11461133            }
    11471134            else if (progress_type == kProgressMusic)
     
    11621149
    11631150void PlaybackBoxMusic::changeVolume(bool up_or_down)
    11641151{
    1165     if (volume_control && output)
     1152    if (volume_control && gPlayer->getOutput())
    11661153    {
    11671154        if (up_or_down)
    1168             output->AdjustCurrentVolume(2);
     1155            gPlayer->getOutput()->AdjustCurrentVolume(2);
    11691156        else
    1170             output->AdjustCurrentVolume(-2);
     1157            gPlayer->getOutput()->AdjustCurrentVolume(-2);
    11711158        showVolume(true);
    11721159    }
    11731160}
    11741161
    11751162void PlaybackBoxMusic::toggleMute()
    11761163{
    1177     if (volume_control && output)
     1164    if (volume_control && gPlayer->getOutput())
    11781165    {
    1179         output->ToggleMute();
     1166        gPlayer->getOutput()->ToggleMute();
    11801167        showVolume(true);
    11811168    }
    11821169}
     
    11841171void PlaybackBoxMusic::showProgressBar()
    11851172{
    11861173
    1187     if (progress_bar) {
    1188 
     1174    if (progress_bar)
     1175    {
    11891176             progress_bar->SetTotal(maxTime);
    11901177             progress_bar->SetUsed(currentTime);
    11911178    }
     
    11941181void PlaybackBoxMusic::showVolume(bool on_or_off)
    11951182{
    11961183    float volume_level;
    1197     if (volume_control && output)
     1184    if (volume_control && gPlayer->getOutput())
    11981185    {
    11991186        if (volume_status)
    12001187        {
    12011188            if (on_or_off)
    12021189            {
    1203                 volume_status->SetUsed(output->GetCurrentVolume());
     1190                volume_status->SetUsed(gPlayer->getOutput()->GetCurrentVolume());
    12041191                volume_status->SetOrder(0);
    12051192                volume_status->refresh();
    12061193                volume_display_timer->changeInterval(2000);
    12071194                if (class LCD *lcd = LCD::Get())
    12081195                    lcd->switchToVolume("Music");
    12091196
    1210                 if (output->GetMute())
     1197                if (gPlayer->getOutput()->GetMute())
    12111198                    volume_level = 0.0;
    12121199                else
    1213                     volume_level = (float)output->GetCurrentVolume() /
     1200                    volume_level = (float)gPlayer->getOutput()->GetCurrentVolume() /
    12141201                                   (float)100;
    12151202
    12161203                if (class LCD *lcd = LCD::Get())
     
    12391226
    12401227void PlaybackBoxMusic::play()
    12411228{
     1229    if (gPlayer->isPlaying())
     1230        gPlayer->stop();
    12421231
    1243     if (isplaying)
    1244         stop();
    1245 
    12461232    if (curMeta)
    12471233        playfile = curMeta->Filename();
    12481234    else
     
    12521238        return;
    12531239    }
    12541240
    1255     QUrl sourceurl(playfile);
    1256     QString sourcename(playfile);
    1257 
    1258     if (!output)
    1259         openOutputDevice();
    1260 
    1261     if (output->GetPause())
     1241    if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
    12621242    {
    1263         pause();
     1243        gPlayer->pause();
    12641244        return;
    12651245    }
    12661246
    1267     if (!sourceurl.isLocalFile())
    1268     {
    1269         StreamInput streaminput(sourceurl);
    1270         streaminput.setup();
    1271         input = streaminput.socket();
    1272     }
    1273     else
    1274         input = new QFile(playfile);
    1275    
    1276     if (decoder && !decoder->factory()->supports(sourcename))
    1277     {
    1278         decoder->removeListener(this);
    1279         decoder = 0;
    1280     }
     1247    gPlayer->setCurrentNode(music_tree_list->getCurrentNode());
     1248    gPlayer->playFile(playfile);
    12811249
    1282     if (!decoder)
    1283     {
    1284         decoder = Decoder::create(sourcename, input, output);
    1285 
    1286         if (!decoder)
    1287         {
    1288             printf("mythmusic: unsupported fileformat\n");
    1289             stopAll();
    1290             return;
    1291         }
    1292         if (sourcename.contains("cda") == 1)
    1293             dynamic_cast<CdDecoder*>(decoder)->setDevice(m_CDdevice);
    1294 
    1295         decoder->setBlockSize(globalBlockSize);
    1296         decoder->addListener(this);
    1297     }
    1298     else
    1299     {
    1300         decoder->setInput(input);
    1301         decoder->setFilename(sourcename);
    1302         decoder->setOutput(output);
    1303     }
    1304 
    13051250    currentTime = 0;
    13061251
    1307     mainvisual->setDecoder(decoder);
    1308     mainvisual->setOutput(output);
     1252    mainvisual->setDecoder(gPlayer->getDecoder());
     1253    mainvisual->setOutput(gPlayer->getOutput());
    13091254    mainvisual->setMetadata(curMeta);
    13101255
    1311     if (decoder->initialize())
     1256    if (gPlayer->isPlaying())
    13121257    {
    1313         if (output)
     1258        if (resumemode == MusicPlayer::RESUME_EXACT &&
     1259                gContext->GetNumSetting("MusicBookmarkPosition", 0) > 0)
    13141260        {
    1315             output->Reset();
    1316         }
    1317 
    1318         decoder->start();
    1319 
    1320         if (resumemode == RESUME_EXACT && gContext->GetNumSetting("MusicBookmarkPosition", 0) > 0)
    1321         {
    13221261            seek(gContext->GetNumSetting("MusicBookmarkPosition", 0));
    13231262            gContext->SaveSetting("MusicBookmarkPosition", 0);
    13241263        }
    1325 
    1326         bannerEnable(curMeta, show_album_art);
    1327         isplaying = true;
    1328         curMeta->setLastPlay();
    1329         curMeta->incPlayCount();
    13301264    }
     1265
     1266    bannerEnable(curMeta, show_album_art);
    13311267}
    13321268
    13331269void PlaybackBoxMusic::visEnable()
    13341270{
    1335     if (!visualizer_status != 2 && isplaying)
     1271    if (!visualizer_status != 2 && gPlayer->isPlaying())
    13361272    {
    13371273        setUpdatesEnabled(false);
    13381274        mainvisual->setGeometry(0, 0, screenwidth, screenheight);
     
    14101346void PlaybackBoxMusic::setTrackOnLCD(Metadata *mdata)
    14111347{
    14121348    LCD *lcd = LCD::Get();
    1413     if (!lcd)
     1349    if (!lcd || !mdata)
    14141350        return;
    14151351
    14161352    // Set the Artist and Tract on the LCD
     
    14211357
    14221358void PlaybackBoxMusic::pause(void)
    14231359{
    1424     if (output)
    1425     {
    1426         isplaying = !isplaying;
    1427         output->Pause(!isplaying); //Note pause doesn't take effect instantly
    1428     }
    1429     // wake up threads
    1430     if (decoder)
    1431     {
    1432         decoder->lock();
    1433         decoder->cond()->wakeAll();
    1434         decoder->unlock();
    1435     }
    1436 
     1360    gPlayer->pause();
    14371361}
    14381362
    1439 void PlaybackBoxMusic::stopDecoder(void)
    1440 {
    1441     if (decoder && decoder->running())
    1442         decoder->stop();
    1443 
    1444     if (decoder)
    1445     {
    1446         decoder->lock();
    1447         decoder->cond()->wakeAll();
    1448         decoder->unlock();
    1449     }
    1450 
    1451     if (decoder)
    1452         decoder->wait();
    1453 }
    1454 
    14551363void PlaybackBoxMusic::stop(void)
    14561364{
    1457     stopDecoder();
     1365    gPlayer->stop();
    14581366
    1459     if (output)
    1460     {
    1461         if (output->GetPause())
    1462         {
    1463             pause();
    1464         }
    1465         output->Reset();
    1466     }
    1467 
    14681367    mainvisual->setDecoder(0);
    14691368    mainvisual->setOutput(0);
    14701369    mainvisual->deleteMetadata();
    14711370
    1472     delete input;
    1473     input = 0;
    1474 
    14751371    QString time_string = getTimeString(maxTime, 0);
    14761372
    14771373    if (time_text)
    14781374        time_text->SetText(time_string);
    14791375    if (info_text)
    14801376        info_text->SetText("");
    1481 
    1482     isplaying = false;
    14831377}
    14841378
    14851379void PlaybackBoxMusic::stopAll()
     
    14891383        lcd->switchToTime();
    14901384    }
    14911385
    1492     stop();
     1386    mainvisual->setDecoder(0);
     1387    mainvisual->setOutput(0);
     1388    mainvisual->deleteMetadata();
    14931389
    1494     if (decoder)
    1495     {
    1496         decoder->removeListener(this);
    1497         decoder = 0;
    1498     }
     1390    gPlayer->stop(true);
    14991391}
    15001392
    15011393void PlaybackBoxMusic::previous()
    15021394{
    1503     if (repeatmode == REPEAT_ALL)
     1395    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
    15041396    {
    15051397        if (music_tree_list->prevActive(true, show_whole_tree))
    15061398            music_tree_list->activate();
     
    15171409
    15181410void PlaybackBoxMusic::next()
    15191411{
    1520     if (repeatmode == REPEAT_ALL)
     1412    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
    15211413    {
    15221414        // Grab the next track after this one. First flag is to wrap around
    15231415        // to the beginning of the list. Second decides if we will traverse up
     
    15411433
    15421434void PlaybackBoxMusic::nextAuto()
    15431435{
    1544     stopDecoder();
    1545 
    1546     isplaying = false;
    1547 
    1548     if (repeatmode == REPEAT_TRACK)
     1436    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_TRACK)
    15491437        play();
    15501438    else
    15511439        next();
     
    15691457
    15701458void PlaybackBoxMusic::seek(int pos)
    15711459{
    1572     if (output)
     1460    if (gPlayer->getOutput())
    15731461    {
    1574         output->Reset();
    1575         output->SetTimecode(pos*1000);
     1462        gPlayer->getOutput()->Reset();
     1463        gPlayer->getOutput()->SetTimecode(pos*1000);
    15761464
    1577         if (decoder && decoder->running())
     1465        if (gPlayer->getDecoder() && gPlayer->getDecoder()->running())
    15781466        {
    1579             decoder->lock();
    1580             decoder->seek(pos);
     1467            gPlayer->getDecoder()->lock();
     1468            gPlayer->getDecoder()->seek(pos);
    15811469
    15821470            if (mainvisual)
    15831471            {
     
    15861474                mainvisual->mutex()->unlock();
    15871475            }
    15881476
    1589             decoder->unlock();
     1477            gPlayer->getDecoder()->unlock();
    15901478        }
    15911479
    1592         if (!isplaying)
     1480        if (!gPlayer->isPlaying())
    15931481        {
    15941482            currentTime = pos;
    15951483            if (time_text)
     
    16141502    }
    16151503}
    16161504
    1617 void PlaybackBoxMusic::setShuffleMode(unsigned int mode)
     1505void PlaybackBoxMusic::setShuffleMode(MusicPlayer::ShuffleMode mode)
    16181506{
    1619     shufflemode = mode;
     1507    MusicPlayer::ShuffleMode shufflemode = mode;
    16201508    QString state;
    16211509
    16221510    switch (shufflemode)
    16231511    {
    1624         case SHUFFLE_INTELLIGENT:
     1512        case MusicPlayer::SHUFFLE_INTELLIGENT:
    16251513            state = tr("Smart");
    16261514            if (class LCD *lcd = LCD::Get())
    16271515                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_SMART);
    16281516            break;
    1629         case SHUFFLE_RANDOM:
     1517        case MusicPlayer::SHUFFLE_RANDOM:
    16301518            state = tr("Rand");
    16311519            if (class LCD *lcd = LCD::Get())
    16321520                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_RAND);
    16331521            break;
    1634         case SHUFFLE_ALBUM:
     1522        case MusicPlayer::SHUFFLE_ALBUM:
    16351523            state = tr("Album");
    16361524            if (class LCD *lcd = LCD::Get())
    16371525                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ALBUM);
    16381526            break;
    1639         case SHUFFLE_ARTIST:
     1527        case MusicPlayer::SHUFFLE_ARTIST:
    16401528            state = tr("Artist");
    16411529            if (class LCD *lcd = LCD::Get())
    16421530                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ARTIST);
     
    16631551
    16641552    bannerEnable(QString("%1: %2").arg(tr("Shuffle")).arg(state), 4000);
    16651553
    1666     if (!shufflemode == SHUFFLE_OFF)
     1554    if (!shufflemode == MusicPlayer::SHUFFLE_OFF)
    16671555        music_tree_list->scrambleParents(true);
    16681556    else
    16691557        music_tree_list->scrambleParents(true);
     
    16751563        music_tree_list->setVisualOrdering(1);
    16761564    music_tree_list->refresh();
    16771565
    1678     if (isplaying)
     1566    if (gPlayer->isPlaying())
    16791567        setTrackOnLCD(curMeta);
    16801568}
    16811569
    16821570void PlaybackBoxMusic::toggleShuffle(void)
    16831571{
    1684     setShuffleMode(++shufflemode % MAX_SHUFFLE_MODES);
     1572    setShuffleMode(gPlayer->toggleShuffleMode());
    16851573}
    16861574
    16871575void PlaybackBoxMusic::increaseRating()
     
    17131601    }
    17141602}
    17151603
    1716 void PlaybackBoxMusic::setRepeatMode(unsigned int mode)
     1604void PlaybackBoxMusic::setRepeatMode(MusicPlayer::RepeatMode mode)
    17171605{
    1718     repeatmode = mode;
     1606    MusicPlayer::RepeatMode repeatmode = mode;
    17191607    QString state;
    17201608
    17211609    switch (repeatmode)
    17221610    {
    1723         case REPEAT_ALL:
     1611        case MusicPlayer::REPEAT_ALL:
    17241612            state = tr("All");
    17251613            if (class LCD *lcd = LCD::Get())
    17261614                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
    17271615            break;
    1728         case REPEAT_TRACK:
     1616        case MusicPlayer::REPEAT_TRACK:
    17291617            state = tr("Track");
    17301618            if (class LCD *lcd = LCD::Get())
    17311619                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
     
    17871675    gContext->SaveSetting("MusicBookmarkPosition", position);
    17881676}
    17891677
    1790 void PlaybackBoxMusic::restorePosition()
     1678void PlaybackBoxMusic::restorePosition(const QString &position)
    17911679{
    17921680    QValueList <int> branches_to_current_node;
    1793     QString s = gContext->GetSetting("MusicBookmark", "");
    17941681
    1795     if (s != "")
     1682    if (position != "")
    17961683    {
    1797         QStringList list = QStringList::split(",", s);
     1684        QStringList list = QStringList::split(",", position);
    17981685
    17991686        for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
    18001687            branches_to_current_node.append((*it).toInt());
     
    18101697            {
    18111698                if (music_tree_list->tryToSetActive(branches_to_current_node))
    18121699                {
    1813                     music_tree_list->select();
     1700                    if (gPlayer->isPlaying())
     1701                    {
     1702                        GenericTree *node = music_tree_list->getCurrentNode();
     1703                        if (node)
     1704                        {
     1705                            curMeta = gMusicData->all_music->getMetadata(node->getInt());
     1706                            updateTrackInfo(curMeta);
     1707
     1708                            maxTime = curMeta->Length() / 1000;
     1709
     1710                            QString time_string = getTimeString(maxTime, 0);
     1711
     1712                            if (showrating)
     1713                            {
     1714                                if (ratings_image)
     1715                                    ratings_image->setRepeat(curMeta->Rating());
     1716                            }
     1717
     1718                            mainvisual->setDecoder(gPlayer->getDecoder());
     1719                            mainvisual->setOutput(gPlayer->getOutput());
     1720                            mainvisual->setMetadata(curMeta);
     1721                            bannerEnable(curMeta, show_album_art);
     1722                        }
     1723                    }
     1724                    else
     1725                        music_tree_list->select();
    18141726                    return;
    18151727                }
    18161728            }
     
    18201732            //we're in show all tree mode - try to restore the position
    18211733            if (music_tree_list->tryToSetActive(branches_to_current_node))
    18221734            {
    1823                 music_tree_list->select();
     1735                if (gPlayer->isPlaying())
     1736                {
     1737                    GenericTree *node = music_tree_list->getCurrentNode();
     1738                    if (node)
     1739                    {
     1740                        curMeta = gMusicData->all_music->getMetadata(node->getInt());
     1741                        updateTrackInfo(curMeta);
     1742
     1743                        maxTime = curMeta->Length() / 1000;
     1744
     1745                        QString time_string = getTimeString(maxTime, 0);
     1746
     1747                        if (showrating)
     1748                        {
     1749                            if (ratings_image)
     1750                                ratings_image->setRepeat(curMeta->Rating());
     1751                        }
     1752
     1753                        mainvisual->setDecoder(gPlayer->getDecoder());
     1754                        mainvisual->setOutput(gPlayer->getOutput());
     1755                        mainvisual->setMetadata(curMeta);
     1756                        bannerEnable(curMeta, show_album_art);
     1757                    }
     1758                }
     1759                else
     1760                    music_tree_list->select();
     1761
    18241762                return;
    18251763            }
    18261764        }
     
    18351773
    18361774void PlaybackBoxMusic::toggleRepeat()
    18371775{
    1838     setRepeatMode(++repeatmode % MAX_REPEAT_MODES);
     1776    setRepeatMode(gPlayer->toggleRepeatMode());
    18391777}
    18401778
    18411779void PlaybackBoxMusic::constructPlaylistTree()
    18421780{
     1781    GenericTree *playlist_tree = gPlayer->getPlaylistTree();
     1782
    18431783    if (playlist_tree)
    18441784        delete playlist_tree;
    18451785
     
    18551795    // whether a node is selectable, how it can be ordered (normal, random,
    18561796    // intelligent, album), etc.
    18571797
    1858     GenericTree *active_playlist_node = all_playlists->writeTree(playlist_tree);
     1798    GenericTree *active_playlist_node = gMusicData->all_playlists->writeTree(playlist_tree);
    18591799    music_tree_list->assignTreeData(playlist_tree);
    18601800    music_tree_list->setCurrentNode(active_playlist_node);
    18611801    tree_is_done = true;
     
    18851825    }
    18861826
    18871827    visual_mode_timer->stop();
    1888     DatabaseBox dbbox(all_playlists, all_music, gContext->GetMainWindow(),
    1889                       m_CDdevice, "music_select", "music-", "database box");
     1828    DatabaseBox dbbox(gContext->GetMainWindow(), m_CDdevice,
     1829                      "music_select", "music-", "database box");
    18901830
    18911831    if (cd_watcher)
    18921832        cd_watcher->stop();
     
    19191859        cd_watcher->start(1000);
    19201860}
    19211861
    1922 void PlaybackBoxMusic::closeEvent(QCloseEvent *event)
    1923 {
    1924     stopAll();
    1925 
    1926     hide();
    1927     event->accept();
    1928 }
    1929 
    1930 void PlaybackBoxMusic::showEvent(QShowEvent *event)
    1931 {
    1932     QWidget::showEvent(event);
    1933 }
    1934 
    19351862void PlaybackBoxMusic::customEvent(QCustomEvent *event)
    19361863{
    19371864    switch ((int)event->type())
     
    20451972        }
    20461973        case DecoderEvent::Error:
    20471974        {
    2048             stopAll();
     1975            stop();
     1976
    20491977            QApplication::sendPostedEvents();
    20501978
    20511979            statusString = tr("Decoder error.");
     
    20611989            break;
    20621990        }
    20631991    }
     1992    //cout << "status string: " << statusString << endl;
    20641993
    20651994    QWidget::customEvent(event);
    20661995}
     
    20952024    setTrackOnLCD(mdata);
    20962025}
    20972026
    2098 void PlaybackBoxMusic::openOutputDevice(void)
    2099 {
    2100     QString adevice;
    2101 
    2102     if (gContext->GetSetting("MusicAudioDevice") == "default")
    2103         adevice = gContext->GetSetting("AudioOutputDevice");
    2104     else
    2105         adevice = gContext->GetSetting("MusicAudioDevice");
    2106 
    2107     // TODO: Error checking that device is opened correctly!
    2108     output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
    2109                                     AUDIOOUTPUT_MUSIC, true,
    2110                                     false /* AC3/DTS pass through */);
    2111     output->setBufferSize(outputBufferSize * 1024);
    2112     output->SetBlocking(false);
    2113     output->addListener(this);
    2114     output->addListener(mainvisual);
    2115     output->addVisual(mainvisual);   
    2116 }
    2117 
    21182027void PlaybackBoxMusic::handleTreeListSignals(int node_int, IntVector *attributes)
    21192028{
    21202029    if (attributes->size() < 4)
     
    21312040        if (node && node->getAttribute(0) == 0)
    21322041        {
    21332042            // copy the selected playlist to the active playlist
    2134             Playlist *playlist = all_playlists->getPlaylist(node->getInt());
     2043            Playlist *playlist = gMusicData->all_playlists->getPlaylist(node->getInt());
    21352044            if (playlist)
    21362045            {
    2137                 all_playlists->getActive()->fillSongsFromSonglist(
     2046                gMusicData->all_playlists->getActive()->fillSongsFromSonglist(
    21382047                        playlist->getSonglist(), false);
    21392048
    21402049                constructPlaylistTree();
     
    21502059    {
    21512060        //  It's a track
    21522061
    2153         curMeta = all_music->getMetadata(node_int);
     2062        GenericTree *currentnode = music_tree_list->getCurrentNode();
     2063        GenericTree *activenode = currentnode;
     2064        if (currentnode && currentnode->childCount() > 0)
     2065        {
     2066            music_tree_list->syncCurrentWithActive();
     2067            activenode = music_tree_list->getCurrentNode();
     2068        }
    21542069
     2070        curMeta = gMusicData->all_music->getMetadata(node_int);
     2071
    21552072        updateTrackInfo(curMeta);
    21562073
    21572074        maxTime = curMeta->Length() / 1000;
     
    21642081                ratings_image->setRepeat(curMeta->Rating());
    21652082        }
    21662083
    2167         if (output && output->GetPause())
    2168             stop();
    2169 
     2084        if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
     2085        {
     2086            gPlayer->stop();
     2087        }
    21702088        if (m_pushedButton && m_pushedButton->Name() == "play_button")
    21712089        {
    21722090            // Play button already pushed, so don't push it again.
     
    21772095        else
    21782096            play();
    21792097
     2098        if (activenode != currentnode)
     2099            music_tree_list->setCurrentNode(currentnode);
     2100
    21802101    }
    21812102    else
    21822103    {
     
    23492270
    23502271    // only give the user a choice of the track to play if shuffle mode is off
    23512272    MythComboBox *playCombo = NULL;
    2352     if (shufflemode == SHUFFLE_OFF)
     2273    if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
    23532274    {
    23542275        playCombo = new MythComboBox(false, popup, "play_combo" );
    23552276        playCombo->insertItem(tr("Continue playing current track"));
     
    23582279        playCombo->setBackgroundOrigin(ParentOrigin);
    23592280        popup->addWidget(playCombo);
    23602281    }
    2361    
     2282
    23622283    MythCheckBox *dupsCheck = new MythCheckBox(popup);
    23632284    dupsCheck->setText(tr("Remove Duplicates"));
    23642285    dupsCheck->setChecked(false);
     
    23882309
    23892310    // if shuffle mode != SHUFFLE_OFF we always try to continue playing
    23902311    // the current track
    2391     if (shufflemode == SHUFFLE_OFF)
     2312    if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
    23922313    {
    23932314        switch (playCombo->currentItem())
    23942315        {
  • mythmusic/mythmusic.pro

     
    3939HEADERS += goom/mmx.h goom/mathtools.h goom/tentacle3d.h goom/v3d.h
    4040HEADERS += editmetadata.h smartplaylist.h search.h genres.h
    4141HEADERS += treebuilders.h importmusic.h directoryfinder.h
    42 HEADERS += filescanner.h libvisualplugin.h
     42HEADERS += filescanner.h libvisualplugin.h musicplayer.h miniplayer.h
    4343
    4444SOURCES += cddecoder.cpp cdrip.cpp decoder.cpp
    4545SOURCES += flacdecoder.cpp flacencoder.cpp maddecoder.cpp main.cpp
     
    5555SOURCES += goom/zoom_filter_mmx.c goom/zoom_filter_xmmx.c goom/mythgoom.cpp
    5656SOURCES += avfdecoder.cpp editmetadata.cpp smartplaylist.cpp search.cpp
    5757SOURCES += treebuilders.cpp importmusic.cpp directoryfinder.cpp
    58 SOURCES += filescanner.cpp libvisualplugin.cpp
     58SOURCES += filescanner.cpp libvisualplugin.cpp musicplayer.cpp miniplayer.cpp
    5959
    6060macx {
    6161    SOURCES -= cddecoder.cpp
     
    6767    #QMAKE_LFLAGS += -flat_namespace -undefined suppress
    6868    QMAKE_LFLAGS += -flat_namespace -undefined error
    6969}
     70
  • mythmusic/music-ui.xml

     
    17921792       </container>
    17931793   </window>
    17941794
     1795   <window name="miniplayer">
     1796
     1797    <font name="currenttitle" face="Arial">
     1798        <color>#ffffff</color>
     1799        <size>20</size>
     1800        <bold>yes</bold>
     1801    </font>
     1802
     1803    <font name="currentartist" face="Arial">
     1804        <color>#ffffff</color>
     1805        <size>16</size>
     1806        <bold>yes</bold>
     1807    </font>
     1808
     1809    <font name="infotext" face="Arial">
     1810        <color>#ffffff</color>
     1811        <size>12</size>
     1812        <bold>yes</bold>
     1813    </font>
     1814
     1815    <container name="player_container">
     1816        <area>0,0,590,170</area>
     1817        <image name="track_info_background" draworder="0" fleximage="no">
     1818            <filename>miniplayer_background.png</filename>
     1819            <position>10,10</position>
     1820        </image>
     1821
     1822        <image name="mm_blackhole_border" draworder="0" fleximage="no">
     1823            <filename>mm_blackhole_border.png</filename>
     1824            <position>20,20</position>
     1825            <staticsize>126,128</staticsize>
     1826        </image>
     1827
     1828        <textarea name="title_text" draworder="1" align="left">
     1829            <font>currenttitle</font>
     1830            <area>160,15,415,34</area>
     1831            <cutdown>yes</cutdown>
     1832        </textarea>
     1833
     1834        <textarea name="artist_text" draworder="1" align="left">
     1835            <font>currentartist</font>
     1836            <area>160,50,415,25</area>
     1837            <cutdown>yes</cutdown>
     1838        </textarea>
     1839
     1840        <textarea name="album_text" draworder="1" align="left">
     1841            <font>currentartist</font>
     1842            <area>160,73,415,25</area>
     1843            <cutdown>yes</cutdown>
     1844        </textarea>
     1845
     1846        <repeatedimage name="ratings_image" draworder="1" fleximage="no">
     1847            <filename>mm_rating.png</filename>
     1848            <position>160,105</position>
     1849            <orientation>LeftToRight</orientation>
     1850        </repeatedimage>
     1851
     1852        <textarea name="info_text" draworder="1" align="left">
     1853            <font>infotext</font>
     1854            <area>160,129,250,25</area>
     1855        </textarea>
     1856
     1857        <textarea name="time_text" draworder="1" align="right">
     1858            <font>currentartist</font>
     1859            <area>375,125,185,25</area>
     1860        </textarea>
     1861
     1862        <image name="cover_image" draworder="2">
     1863            <filename>mm_nothumb.png</filename>
     1864            <position>22,22</position>
     1865            <staticsize>122,124</staticsize>
     1866        </image>
     1867
     1868    </container>
     1869
     1870  </window>
     1871
    17951872</mythuitheme>
  • mythmusic/miniplayer.cpp

     
     1#include <iostream>
     2using namespace std;
     3
     4// qt
     5#include <qpixmap.h>
     6#include <qimage.h>
     7#include <qapplication.h>
     8
     9// mythtv
     10#include <mythtv/mythcontext.h>
     11#include <mythtv/mythdialogs.h>
     12#include <mythtv/uitypes.h>
     13#include <mythtv/lcddevice.h>
     14
     15// mythmusic
     16#include "miniplayer.h"
     17#include "musicplayer.h"
     18#include "decoder.h"
     19
     20MiniPlayer::MiniPlayer(MythMainWindow *parent,
     21                    MusicPlayer *parentPlayer,
     22                    const char *name,
     23                    bool setsize)
     24            : MythThemedDialog(parent, name, setsize)
     25{
     26    setFrameStyle(QFrame::Panel | QFrame::Raised);
     27    setLineWidth(1);
     28    m_parentPlayer = parentPlayer;
     29
     30    m_displayTimer = new QTimer(this);
     31    connect(m_displayTimer, SIGNAL(timeout()), this, SLOT(timerTimeout()));
     32
     33    m_infoTimer = new QTimer(this);
     34    connect(m_infoTimer, SIGNAL(timeout()), this, SLOT(showInfoTimeout()));
     35
     36    wireupTheme();
     37
     38    gPlayer->setListener(this);
     39
     40    if (gPlayer->isPlaying() && gPlayer->getCurrentMetadata())
     41    {
     42        m_maxTime = gPlayer->getCurrentMetadata()->Length() / 1000;
     43        updateTrackInfo(gPlayer->getCurrentMetadata());
     44    }
     45
     46    m_showingInfo = false;
     47}
     48
     49MiniPlayer::~MiniPlayer(void)
     50{
     51    gPlayer->setListener(NULL);
     52
     53    m_displayTimer->deleteLater();
     54    m_displayTimer = NULL;
     55
     56    m_infoTimer->deleteLater();
     57    m_infoTimer = NULL;
     58
     59    if (class LCD *lcd = LCD::Get())
     60        lcd->switchToTime ();
     61}
     62
     63void MiniPlayer::showPlayer(int showTime)
     64{
     65    m_displayTimer->start(showTime * 1000, true);
     66    exec();
     67}
     68
     69void MiniPlayer::timerTimeout(void)
     70{
     71    done(Accepted);
     72}
     73
     74void MiniPlayer::wireupTheme(void)
     75{
     76    QString theme_file = QString("music-");
     77
     78    if (!loadThemedWindow("miniplayer", theme_file))
     79    {
     80        VERBOSE(VB_GENERAL, "MiniPlayer: cannot load theme!");
     81        done(0);
     82        return;
     83    }
     84
     85    // get dialog size from player_container area
     86    LayerSet *container = getContainer("player_container");
     87
     88    if (!container)
     89    {
     90        cerr << "MiniPlayer: cannot find the 'player_container'"
     91                " in your theme" << endl;
     92        done(0);
     93        return;
     94    }
     95
     96    m_popupWidth = container->GetAreaRect().width();
     97    m_popupHeight = container->GetAreaRect().height();
     98    setFixedSize(QSize(m_popupWidth, m_popupHeight));
     99
     100    int xbase, width, ybase, height;
     101    float wmult, hmult;
     102    gContext->GetScreenSettings(xbase, width, wmult, ybase, height, hmult);
     103    QRect tlwg = QRect(0, 0, width, height);
     104
     105    QPoint newpos;
     106
     107    PlayerPosition preferredPos = MP_POSTOPDIALOG;
     108
     109    if (preferredPos == MP_POSTOPDIALOG)
     110    {
     111        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2, 5);
     112        this->move(newpos);
     113    }
     114    else if (preferredPos == MP_POSBOTTOMDIALOG)
     115    {
     116        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
     117                        tlwg.height() - 5 - m_popupHeight);
     118        this->move(newpos);
     119    }
     120    else if (preferredPos == MP_POSCENTERDIALOG)
     121    {
     122        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
     123                        tlwg.height() / 2 - m_popupHeight / 2);
     124        this->move(newpos);
     125    }
     126
     127    m_titleText = getUITextType("title_text");
     128    m_artistText = getUITextType("artist_text");
     129    m_timeText = getUITextType("time_text");
     130    m_infoText = getUITextType("info_text");
     131    m_albumText = getUITextType("album_text");
     132    m_ratingsImage = getUIRepeatedImageType("ratings_image");
     133    m_coverImage = getUIImageType("cover_image");
     134}
     135
     136void MiniPlayer::show()
     137{
     138    grabKeyboard();
     139
     140    MythDialog::show();
     141}
     142
     143void MiniPlayer::hide()
     144{
     145    releaseKeyboard();
     146
     147    MythDialog::hide();
     148}
     149
     150void MiniPlayer::keyPressEvent(QKeyEvent *e)
     151{
     152    bool handled = false;
     153    QStringList actions;
     154    if (gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions, false))
     155    {
     156        for (unsigned int i = 0; i < actions.size() && !handled; i++)
     157        {
     158            QString action = actions[i];
     159            handled = true;
     160            if (action == "ESCAPE")
     161                done(0);
     162            else if (action == "SELECT")
     163                    m_displayTimer->stop();
     164            else if (action == "NEXTTRACK")
     165            {
     166                gPlayer->next();
     167            }
     168            else if (action == "PREVTRACK")
     169            {
     170                gPlayer->previous();
     171            }
     172            else if (action == "FFWD")
     173            {
     174                seekforward();
     175            }
     176            else if (action == "RWND")
     177            {
     178                seekback();
     179            }
     180            else if (action == "PAUSE")
     181            {
     182                if (gPlayer->isPlaying())
     183                    gPlayer->pause();
     184                else
     185                {
     186                    if (gPlayer->isPlaying())
     187                        gPlayer->stop();
     188
     189                    if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
     190                    {
     191                        gPlayer->pause();
     192                        return;
     193                    }
     194
     195                    gPlayer->play();
     196                }
     197            }
     198            else if (action == "STOP")
     199            {
     200                gPlayer->stop();
     201
     202                QString time_string = getTimeString(m_maxTime, 0);
     203
     204                if (m_timeText)
     205                    m_timeText->SetText(time_string);
     206                if (m_infoText)
     207                    m_infoText->SetText("");
     208            }
     209            else if (action == "VOLUMEDOWN")
     210            {
     211                if (gPlayer->getOutput())
     212                {
     213                    gPlayer->getOutput()->AdjustCurrentVolume(-2);
     214                    showVolume();
     215                }
     216            }
     217            else if (action == "VOLUMEUP")
     218            {
     219                if (gPlayer->getOutput())
     220                {
     221                    gPlayer->getOutput()->AdjustCurrentVolume(2);
     222                    showVolume();
     223                }
     224            }
     225            else if (action == "MUTE")
     226            {
     227                if (gPlayer->getOutput())
     228                {
     229                    gPlayer->getOutput()->ToggleMute();
     230
     231                    if (m_infoText)
     232                    {
     233                        m_showingInfo = true;
     234                        if (gPlayer->getOutput()->GetMute())
     235                            m_infoText->SetText(tr("Mute: On"));
     236                        else
     237                            m_infoText->SetText(tr("Mute: Off"));
     238
     239                        m_infoTimer->start(5000, true);
     240                    }
     241                }
     242            }
     243            else if (action == "THMBUP")
     244                increaseRating();
     245            else if (action == "THMBDOWN")
     246                decreaseRating();
     247            else if (action == "1")
     248            {
     249                gPlayer->toggleShuffleMode();
     250                showShuffleMode();
     251            }
     252            else if (action == "2")
     253            {
     254                gPlayer->toggleRepeatMode();
     255                showRepeatMode();
     256            }
     257            else
     258                handled = false;
     259        }
     260    }
     261}
     262
     263void MiniPlayer::customEvent(QCustomEvent *event)
     264{
     265
     266    switch ((int)event->type())
     267    {
     268        case OutputEvent::Playing:
     269        {
     270            if (gPlayer->getCurrentMetadata())
     271            {
     272                m_maxTime = gPlayer->getCurrentMetadata()->Length() / 1000;
     273                updateTrackInfo(gPlayer->getCurrentMetadata());
     274            }
     275            break;
     276        }
     277
     278        case OutputEvent::Buffering:
     279        {
     280            break;
     281        }
     282
     283        case OutputEvent::Paused:
     284        {
     285            break;
     286        }
     287
     288        case OutputEvent::Info:
     289       {
     290            OutputEvent *oe = (OutputEvent *) event;
     291
     292            int rs;
     293            m_currTime = rs = oe->elapsedSeconds();
     294
     295            QString time_string = getTimeString(rs, m_maxTime);
     296
     297            QString info_string;
     298
     299            //  Hack around for cd bitrates
     300            if (oe->bitrate() < 2000)
     301            {
     302                info_string.sprintf("%d "+tr("kbps")+ "   %.1f "+ tr("kHz")+ "   %s "+ tr("ch"),
     303                                   oe->bitrate(), float(oe->frequency()) / 1000.0,
     304                                   oe->channels() > 1 ? "2" : "1");
     305            }
     306            else
     307            {
     308                info_string.sprintf("%.1f "+ tr("kHz")+ "   %s "+ tr("ch"),
     309                                   float(oe->frequency()) / 1000.0,
     310                                   oe->channels() > 1 ? "2" : "1");
     311            }
     312
     313            if (m_timeText)
     314                m_timeText->SetText(time_string);
     315            if (m_infoText && !m_showingInfo)
     316                m_infoText->SetText(info_string);
     317
     318            if (gPlayer->getCurrentMetadata())
     319            {
     320                if (class LCD *lcd = LCD::Get())
     321                {
     322                    float percent_heard = m_maxTime <=0 ? 0.0 :
     323                            ((float)rs / (float)gPlayer->getCurrentMetadata()->Length()) * 1000.0;
     324
     325                    QString lcd_time_string = time_string;
     326
     327                    // if the string is longer than the LCD width, remove all spaces
     328                    if (time_string.length() > lcd->getLCDWidth())
     329                        lcd_time_string.remove(' ');
     330
     331                    lcd->setMusicProgress(lcd_time_string, percent_heard);
     332                }
     333            }
     334            break;
     335        }
     336        case OutputEvent::Error:
     337        {
     338            break;
     339        }
     340        case DecoderEvent::Stopped:
     341        {
     342            break;
     343        }
     344        case DecoderEvent::Finished:
     345        {
     346            if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_TRACK)
     347               gPlayer->play();
     348            else
     349                gPlayer->next();
     350            break;
     351        }
     352        case DecoderEvent::Error:
     353        {
     354            break;
     355        }
     356    }
     357    QObject::customEvent(event);
     358}
     359
     360QString MiniPlayer::getTimeString(int exTime, int maxTime)
     361{
     362    QString time_string;
     363
     364    int eh = exTime / 3600;
     365    int em = (exTime / 60) % 60;
     366    int es = exTime % 60;
     367
     368    int maxh = maxTime / 3600;
     369    int maxm = (maxTime / 60) % 60;
     370    int maxs = maxTime % 60;
     371
     372    if (maxTime <= 0)
     373    {
     374        if (eh > 0)
     375            time_string.sprintf("%d:%02d:%02d", eh, em, es);
     376        else
     377            time_string.sprintf("%02d:%02d", em, es);
     378    }
     379    else
     380    {
     381        if (maxh > 0)
     382            time_string.sprintf("%d:%02d:%02d / %02d:%02d:%02d", eh, em,
     383                    es, maxh, maxm, maxs);
     384        else
     385            time_string.sprintf("%02d:%02d / %02d:%02d", em, es, maxm,
     386                    maxs);
     387    }
     388
     389    return time_string;
     390}
     391
     392void MiniPlayer::updateTrackInfo(Metadata *mdata)
     393{
     394    if (m_titleText)
     395        m_titleText->SetText(mdata->FormatTitle());
     396    if (m_artistText)
     397        m_artistText->SetText(mdata->FormatArtist());
     398    if (m_albumText)
     399        m_albumText->SetText(mdata->Album());
     400    if (m_ratingsImage)
     401        m_ratingsImage->setRepeat(mdata->Rating());
     402
     403    if (m_coverImage)
     404    {
     405        QImage image = gPlayer->getCurrentMetadata()->getAlbumArt(IT_FRONTCOVER);
     406        if (!image.isNull())
     407            m_coverImage->SetImage(
     408                    QPixmap(image.smoothScale(m_coverImage->GetSize(true))));
     409        m_coverImage->refresh();
     410    }
     411
     412    LCD *lcd = LCD::Get();
     413    if (lcd)
     414    {
     415        // Set the Artist and Track on the LCD
     416        lcd->switchToMusic(mdata->Artist(),
     417                       mdata->Album(),
     418                       mdata->Title());
     419    }
     420}
     421
     422void MiniPlayer::seekforward(void)
     423{
     424    int nextTime = m_currTime + 5;
     425    if (nextTime > m_maxTime)
     426        nextTime = m_maxTime;
     427    seek(nextTime);
     428}
     429
     430void MiniPlayer::seekback(void)
     431{
     432    int nextTime = m_currTime - 5;
     433    if (nextTime < 0)
     434        nextTime = 0;
     435    seek(nextTime);
     436}
     437
     438void MiniPlayer::seek(int pos)
     439{
     440    if (gPlayer->getOutput())
     441    {
     442        gPlayer->getOutput()->Reset();
     443        gPlayer->getOutput()->SetTimecode(pos*1000);
     444
     445        if (gPlayer->getDecoder() && gPlayer->getDecoder()->running())
     446        {
     447            gPlayer->getDecoder()->lock();
     448            gPlayer->getDecoder()->seek(pos);
     449            gPlayer->getDecoder()->unlock();
     450        }
     451
     452        if (!gPlayer->isPlaying())
     453        {
     454            m_currTime = pos;
     455            if (m_timeText)
     456                m_timeText->SetText(getTimeString(pos, m_maxTime));
     457
     458            //showProgressBar();
     459
     460            if (class LCD *lcd = LCD::Get())
     461            {
     462                float percent_heard = m_maxTime <= 0 ? 0.0 : ((float)pos /
     463                                      (float)m_maxTime);
     464
     465                QString lcd_time_string = getTimeString(pos, m_maxTime);
     466
     467                // if the string is longer than the LCD width, remove all spaces
     468                if (lcd_time_string.length() > lcd->getLCDWidth())
     469                    lcd_time_string.remove(' ');
     470
     471                lcd->setMusicProgress(lcd_time_string, percent_heard);
     472            }
     473        }
     474    }
     475}
     476
     477void MiniPlayer::increaseRating(void)
     478{
     479    Metadata *curMeta = gPlayer->getCurrentMetadata();
     480
     481    if (!curMeta)
     482        return;
     483
     484    if (m_ratingsImage)
     485    {
     486        curMeta->incRating();
     487        curMeta->persist();
     488        m_ratingsImage->setRepeat(curMeta->Rating());
     489
     490        // if all_music is still in scope we need to keep that in sync
     491        if (gMusicData->all_music)
     492        {
     493            if (gPlayer->getCurrentNode())
     494            {
     495                Metadata *mdata = gMusicData->all_music->getMetadata(gPlayer->getCurrentNode()->getInt());
     496                if (mdata)
     497                {
     498                    mdata->incRating();
     499                }
     500            }
     501        }
     502    }
     503}
     504
     505void MiniPlayer::decreaseRating(void)
     506{
     507    Metadata *curMeta = gPlayer->getCurrentMetadata();
     508
     509    if (!curMeta)
     510        return;
     511
     512    if (m_ratingsImage)
     513    {
     514        curMeta->decRating();
     515        curMeta->persist();
     516        m_ratingsImage->setRepeat(curMeta->Rating());
     517
     518        // if all_music is still in scope we need to keep that in sync
     519        if (gMusicData->all_music)
     520        {
     521            if (gPlayer->getCurrentNode())
     522            {
     523                Metadata *mdata = gMusicData->all_music->getMetadata(gPlayer->getCurrentNode()->getInt());
     524                if (mdata)
     525                {
     526                    mdata->decRating();
     527                }
     528            }
     529        }
     530    }
     531}
     532
     533void MiniPlayer::showInfoTimeout(void)
     534{
     535    m_showingInfo = false;
     536    LCD *lcd = LCD::Get();
     537    Metadata * mdata = gPlayer->getCurrentMetadata();
     538
     539    if (lcd && mdata)
     540    {
     541        // Set the Artist and Track on the LCD
     542        lcd->switchToMusic(mdata->Artist(),
     543                       mdata->Album(),
     544                       mdata->Title());
     545    }
     546}
     547
     548void MiniPlayer::showShuffleMode(void)
     549{
     550    if (m_infoText)
     551    {
     552        m_infoTimer->stop();
     553        QString msg = tr("Shuffle Mode: ");
     554        switch (gPlayer->getShuffleMode())
     555        {
     556            case MusicPlayer::SHUFFLE_INTELLIGENT:
     557                msg += tr("Smart");
     558                if (class LCD *lcd = LCD::Get())
     559                    lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_SMART);
     560                break;
     561            case MusicPlayer::SHUFFLE_RANDOM:
     562                msg += tr("Rand");
     563                if (class LCD *lcd = LCD::Get())
     564                    lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_RAND);
     565                break;
     566            case MusicPlayer::SHUFFLE_ALBUM:
     567                msg += tr("Album");
     568                if (class LCD *lcd = LCD::Get())
     569                    lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ALBUM);
     570                break;
     571            case MusicPlayer::SHUFFLE_ARTIST:
     572                msg += tr("Artist");
     573                if (class LCD *lcd = LCD::Get())
     574                    lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ARTIST);
     575                break;
     576            default:
     577                msg += tr("None");
     578                if (class LCD *lcd = LCD::Get())
     579                    lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_NONE);
     580                break;
     581        }
     582
     583        m_showingInfo = true;
     584        m_infoText->SetText(msg);
     585        m_infoTimer->start(5000, true);
     586    }
     587}
     588
     589void MiniPlayer::showRepeatMode(void)
     590{
     591    if (m_infoText)
     592    {
     593        m_infoTimer->stop();
     594        QString msg = tr("Repeat Mode: ");
     595        switch (gPlayer->getRepeatMode())
     596        {
     597            case MusicPlayer::REPEAT_ALL:
     598                msg += tr("All");
     599                if (class LCD *lcd = LCD::Get())
     600                    lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
     601                break;
     602            case MusicPlayer::REPEAT_TRACK:
     603                msg += tr("Track");
     604                if (class LCD *lcd = LCD::Get())
     605                    lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
     606                break;
     607            default:
     608                msg += tr("None");
     609                if (class LCD *lcd = LCD::Get())
     610                    lcd->setMusicRepeat (LCD::MUSIC_REPEAT_NONE);
     611                break;
     612        }
     613
     614        m_showingInfo = true;
     615        m_infoText->SetText(msg);
     616        m_infoTimer->start(5000, true);
     617    }
     618}
     619
     620void MiniPlayer::showVolume(void)
     621{
     622    if (m_infoText)
     623    {
     624        m_infoTimer->stop();
     625        QString msg = tr("Volume: ");
     626        float level;
     627
     628        level = (float)gPlayer->getOutput()->GetCurrentVolume();
     629
     630        if (gPlayer->getOutput()->GetMute())
     631        {
     632            if (class LCD *lcd = LCD::Get())
     633            {
     634                lcd->switchToVolume("Music (muted)");
     635                lcd->setVolumeLevel(level / (float)100);
     636            }
     637            msg += QString::number((int) level) + "% " + tr("(muted)");
     638        }
     639        else
     640        {
     641            if (class LCD *lcd = LCD::Get())
     642            {
     643                lcd->switchToVolume("Music");
     644                lcd->setVolumeLevel(level / (float)100);
     645            }
     646            msg += QString::number((int) level) + "%";
     647        }
     648
     649        m_showingInfo = true;
     650        m_infoText->SetText(msg);
     651        m_infoTimer->start(5000, true);
     652    }
     653}
  • mythmusic/metadata.cpp

     
    11#include <iostream>
     2
     3// qt
    24#include <qapplication.h>
    35#include <qregexp.h>
    46#include <qdatetime.h>
     
    68
    79using namespace std;
    810
     11// mythtv
    912#include <mythtv/mythcontext.h>
    1013#include <mythtv/mythwidgets.h>
    1114#include <mythtv/mythdbcon.h>
    1215
     16// mythmusic
    1317#include "metadata.h"
     18#include "metaiotaglib.h"
    1419#include "treebuilders.h"
     20#include "playlist.h"
    1521
     22
     23// this is the global MusicData object shared thoughout MythMusic
     24MusicData  *gMusicData = NULL;
     25
    1626static QString thePrefix = "the ";
    1727
    1828bool operator==(const Metadata& a, const Metadata& b)
     
    7080    query.bindValue(":LASTPLAY", m_lastplay);
    7181    query.bindValue(":ID", m_id);
    7282
    73     if (!query.exec() || query.numRowsAffected() < 1)
     83    if (!query.exec())
    7484        MythContext::DBError("music persist", query);
    7585}
    7686
     
    725735    return image;
    726736}
    727737
     738// static function to get a metadata object given a track id
     739// it's upto the caller to delete the returned object when finished
     740Metadata *Metadata::getMetadataFromID(int id)
     741{
     742    Metadata *meta = NULL;
     743
     744    QString aquery = "SELECT music_songs.song_id, music_artists.artist_name, music_comp_artists.artist_name AS compilation_artist, "
     745                     "music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
     746                     "music_songs.track, music_songs.length, CONCAT_WS('/', "
     747                     "music_directories.path, music_songs.filename) AS filename, "
     748                     "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_albums.compilation, "
     749                     "music_songs.format "
     750                     "FROM music_songs "
     751                     "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
     752                     "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
     753                     "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
     754                     "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
     755                     "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
     756                     "WHERE music_songs.song_id = :TRACKID;";
     757
     758    QString filename, artist, album, title;
     759
     760    MSqlQuery query(MSqlQuery::InitCon());
     761    query.prepare(aquery);
     762    query.bindValue(":TRACKID", id);
     763    query.exec();
     764
     765    if (query.isActive() && query.size() > 0)
     766    {
     767        query.next();
     768        filename = QString::fromUtf8(query.value(9).toString());
     769        if (!filename.contains("://"))
     770            filename = m_startdir + filename;
     771
     772        artist = QString::fromUtf8(query.value(1).toString());
     773        if (artist.isEmpty())
     774            artist = QObject::tr("Unknown Artist");
     775
     776        album = QString::fromUtf8(query.value(3).toString());
     777        if (album.isEmpty())
     778            album = QObject::tr("Unknown Album");
     779
     780        title = QString::fromUtf8(query.value(4).toString());
     781        if (title.isEmpty())
     782            title = QObject::tr("Unknown Title");
     783
     784        meta = new Metadata(
     785            filename,
     786            artist,
     787            QString::fromUtf8(query.value(2).toString()),
     788            album,
     789            title,
     790            QString::fromUtf8(query.value(5).toString()),
     791            query.value(6).toInt(),
     792            query.value(7).toInt(),
     793            query.value(8).toInt(),
     794            query.value(0).toInt(),
     795            query.value(10).toInt(), //rating
     796            query.value(11).toInt(), //playcount
     797            query.value(12).toString(), //lastplay
     798            (query.value(13).toInt() > 0), //compilation
     799            query.value(14).toString()); //format
     800    }
     801    else
     802    {
     803         VERBOSE(VB_IMPORTANT, QString("Track %1 not found!!").arg(id));
     804         return NULL;
     805    }
     806
     807    return meta;
     808}
     809
     810//--------------------------------------------------------------------------
     811
    728812MetadataLoadingThread::MetadataLoadingThread(AllMusic *parent_ptr)
    729813{
    730814    parent = parent_ptr;
     
    15581642
    15591643    return type;
    15601644}
     1645
     1646MusicData::MusicData(void)
     1647{
     1648    paths = "";
     1649    startdir = "";
     1650    all_playlists = NULL;
     1651    all_music = NULL;
     1652    runPost = false;
     1653}
     1654
     1655MusicData::~MusicData(void)
     1656{
     1657    if (all_playlists)
     1658    {
     1659        delete all_playlists;
     1660        all_playlists = NULL;
     1661    }
     1662
     1663    if (all_music)
     1664    {
     1665        delete all_music;
     1666        all_music = NULL;
     1667    }
     1668}
     1669
     1670
  • mythmusic/databasebox.h

     
    2020{
    2121  public:
    2222
    23     ReadCDThread(const QString &dev,
    24                  PlaylistsContainer *all_the_playlist, AllMusic *all_the_music);
     23    ReadCDThread(const QString &dev);
    2524    virtual void run();
    2625    bool    statusChanged(){return cd_status_changed;}
    2726    QMutex  *getLock(){return &music_lock;}
     
    2928  private:
    3029
    3130    QString             m_CDdevice;
    32     AllMusic*           all_music;
    33     PlaylistsContainer* the_playlists;
    3431    bool                cd_status_changed;
    3532    QMutex              music_lock;
    3633};
     
    3936{
    4037    Q_OBJECT
    4138  public:
    42     DatabaseBox(PlaylistsContainer *all_playlists,
    43                 AllMusic *music_ptr, MythMainWindow *parent,
     39    DatabaseBox(MythMainWindow *parent,
    4440                const QString dev, const QString &window_name,
    4541                const QString &theme_filename, const char *name = 0);
    4642   ~DatabaseBox();
     
    4844    void dealWithTracks(PlaylistItem *item_ptr);
    4945    void setCDTitle(const QString& title);
    5046    void fillCD(void);
    51    
     47
    5248  protected slots:
    5349    void selected(UIListGenericTree *);
    5450    void entered(UIListTreeType *, UIListGenericTree *);
     
    8177    void doPlaylistPopup(TreeCheckItem *item_ptr);
    8278    void doActivePopup(PlaylistTitle *item_ptr);
    8379    void checkParent(UIListGenericTree *);
    84  
     80
    8581    void checkTree(UIListGenericTree *startingpoint = NULL);
    8682    QPixmap getPixmap(QString &level);
    8783
     
    8985    UIListTreeType      *tree;
    9086
    9187    CDCheckItem         *cditem;
    92     PlaylistsContainer  *the_playlists;
    93    
     88
    9489    QString             m_CDdevice;
    95     AllMusic            *all_music;
    9690    bool                holding_track;
    9791    PlaylistTrack       *track_held;
    9892    TreeCheckItem       *allmusic;
    9993    TreeCheckItem       *alllists;
    10094    PlaylistTitle       *allcurrent;
    10195    Playlist            *active_playlist;
    102    
     96
    10397    MythPopupBox        *active_popup;
    10498    MythRemoteLineEdit  *active_pl_edit;
    10599
  • mythmusic/metadata.h

     
    11#ifndef METADATA_H_
    22#define METADATA_H_
    33
     4// qt
    45#include <qstring.h>
    56#include <qstringlist.h>
    67#include <qptrlist.h>
     
    89#include <qmap.h>
    910#include <qthread.h>
    1011
    11 #include "treecheckitem.h"
     12// mythtv
    1213#include <mythtv/uitypes.h>
    1314
     15// mythmusic
     16#include "treecheckitem.h"
    1417
     18
    1519class AllMusic;
    1620class CoverArt;
     21class PlaylistsContainer;
    1722
    1823enum ImageType
    1924{
     
    2530    IT_LAST
    2631};
    2732
    28 #include "metaiotaglib.h"
    29 
    3033typedef struct AlbumArtImage
    3134{
    3235    int       id;
     
    3740    bool      embedded;
    3841} AlbumArtImage;
    3942
    40 //typedef QValueList<struct AlbumArtImage> AlbumArtList;
    4143
    4244class Metadata
    4345{
     
    183185    static QString GetStartdir() { return m_startdir; }
    184186
    185187    static QStringList fillFieldList(QString field);
     188    static Metadata *getMetadataFromID(int id);
    186189
    187190    QImage getAlbumArt(ImageType type);
    188191
     
    307310    double              m_lastplayMax;
    308311};
    309312
     313//---------------------------------------------------------------------------
     314
    310315class MetadataLoadingThread : public QThread
    311316{
    312317
     
    320325    AllMusic *parent;
    321326};
    322327
     328//---------------------------------------------------------------------------
     329
    323330class AllMusic
    324331{
    325332    //  One class to read the data once at mythmusic start
     
    393400
    394401};
    395402
     403//----------------------------------------------------------------------------
     404
     405class MusicData
     406{
     407  public:
     408
     409    MusicData();
     410    ~MusicData();
     411
     412    QString             paths;
     413    QString             startdir;
     414    PlaylistsContainer *all_playlists;
     415    AllMusic           *all_music;
     416    bool                runPost;
     417};
     418
     419// This global variable contains the MusicData instance for the application
     420extern MPUBLIC MusicData *gMusicData;
     421
     422//----------------------------------------------------------------------------
     423
    396424class AlbumArtImages: public QObject
    397425{
    398426  Q_OBJECT
  • mythmusic/musicplayer.h

     
     1#ifndef MUSICPLAYER_H_
     2#define MUSICPLAYER_H_
     3
     4#include <iostream>
     5
     6#include <mythtv/mythdialogs.h>
     7#include <mythtv/audiooutput.h>
     8
     9#include "metadata.h"
     10
     11class Decoder;
     12class AudioOutput;
     13class MainVisual;
     14
     15class MusicPlayer : public QObject
     16{
     17  //Q_OBJECT
     18
     19  public:
     20
     21     MusicPlayer(QObject *parent, const QString &dev);
     22    ~MusicPlayer(void);
     23
     24    void playFile(const QString &filename);
     25    void playFile(const Metadata &meta);
     26
     27    void addFile(const QString &filename) {};
     28    void addFile(const Metadata &meta) {};
     29
     30    void setListener(QObject *listener);
     31    void setVisual(MainVisual *visual);
     32    void setCDDevice(const QString &dev) { m_CDdevice = dev; }
     33
     34    void mute(void) {};
     35    void unMute(void) {};
     36    void setVolume(void) {};
     37
     38    void play(void);
     39    void stop(bool stopAll = false);
     40    void pause(void);
     41    void next(void);
     42    void previous(void);
     43
     44    void nextAuto(void);
     45
     46    bool isPlaying(void) { return m_isPlaying; }
     47    bool hasClient(void) { return (m_listener != NULL); }
     48
     49    Decoder     *getDecoder(void) { return m_decoder; }
     50    AudioOutput *getOutput(void) { return m_output; }
     51
     52    GenericTree *getPlaylistTree() { return m_playlistTree; }
     53    void         setCurrentNode(GenericTree *node) { m_currentNode = node; }
     54    GenericTree *getCurrentNode(void) { return m_currentNode; }
     55
     56    QString      getRouteToCurrent(void);
     57
     58    void         savePosition(void);
     59    void         seek(int pos);
     60
     61    Metadata    *getCurrentMetadata(void);
     62    void         refreshMetadata(void);
     63
     64    void showMiniPlayer(void);
     65
     66    enum RepeatMode
     67    { REPEAT_OFF = 0,
     68      REPEAT_TRACK,
     69      REPEAT_ALL,
     70      MAX_REPEAT_MODES
     71    };
     72    enum ShuffleMode
     73    { SHUFFLE_OFF = 0,
     74      SHUFFLE_RANDOM,
     75      SHUFFLE_INTELLIGENT,
     76      SHUFFLE_ALBUM,
     77      SHUFFLE_ARTIST,
     78      MAX_SHUFFLE_MODES
     79    };
     80
     81    enum ResumeMode
     82    { RESUME_OFF,
     83      RESUME_TRACK,
     84      RESUME_EXACT,
     85      MAX_RESUME_MODES
     86    };
     87
     88    RepeatMode getRepeatMode(void) { return m_repeatMode; }
     89    void       setRepeatMode(RepeatMode mode) { m_repeatMode = mode; }
     90    RepeatMode toggleRepeatMode(void);
     91
     92    ShuffleMode getShuffleMode(void) { return m_shuffleMode; }
     93    void        setShuffleMode(ShuffleMode mode) { m_shuffleMode = mode; }
     94    ShuffleMode toggleShuffleMode(void);
     95
     96    ResumeMode  getResumeMode(void) { return m_resumeMode; }
     97
     98  protected:
     99    void customEvent(QCustomEvent *event);
     100
     101  private:
     102    void stopDecoder(void);
     103    void openOutputDevice(void);
     104    QString getFilenameFromID(int id);
     105
     106    GenericTree *m_playlistTree;
     107
     108    GenericTree *m_currentNode;
     109    Metadata    *m_currentMetadata;
     110    QString      m_currentFile;
     111    int          m_currentTime;
     112
     113    QIODevice   *m_input;
     114    AudioOutput *m_output;
     115    Decoder     *m_decoder;
     116
     117    QObject     *m_listener;
     118    MainVisual  *m_visual;
     119
     120    QString      m_CDdevice;
     121
     122    bool         m_isPlaying;
     123    bool         m_isAutoplay;
     124
     125    ShuffleMode  m_shuffleMode;
     126    RepeatMode   m_repeatMode;
     127    ResumeMode   m_resumeMode;
     128};
     129
     130// This global variable contains the MusicPlayer instance for the application
     131extern MPUBLIC MusicPlayer *gPlayer;
     132
     133#endif
  • mythmusic/databasebox.cpp

     
    2121#include <mythtv/uitypes.h>
    2222#include <mythtv/uilistbtntype.h>
    2323
    24 DatabaseBox::DatabaseBox(PlaylistsContainer *all_playlists,
    25                          AllMusic *music_ptr, MythMainWindow *parent,
     24DatabaseBox::DatabaseBox(MythMainWindow *parent,
    2625                         const QString dev, const QString &window_name,
    2726                         const QString &theme_filename, const char *name)
    2827           : MythThemedDialog(parent, window_name, theme_filename, name)
    2928{
    3029    m_CDdevice = dev;
    31     the_playlists = all_playlists;
    3230    active_playlist = NULL;
    3331
    34     if (!music_ptr)
     32    if (!gMusicData->all_music)
    3533    {
    3634        VERBOSE(VB_IMPORTANT, "We are not going to get very far with a null "
    3735                "pointer to metadata");
     36        exit(0);
    3837    }
    39     all_music = music_ptr;
    4038
    4139    //  Do we check the CD?
    4240    cd_checking_flag = false;
     
    117115        // Start the CD checking thread, and set up a timer to make it check
    118116        // occasionally
    119117
    120         cd_reader_thread = new ReadCDThread(m_CDdevice,
    121                                             the_playlists, all_music);
     118        cd_reader_thread = new ReadCDThread(m_CDdevice);
    122119
    123120        // filling initialy before thread running
    124121        fillCD();
     
    150147        delete cd_reader_thread;
    151148    }
    152149
    153     all_music->cleanOutThreads();
    154     the_playlists->cleanOutThreads();
     150    gMusicData->all_music->cleanOutThreads();
     151    gMusicData->all_playlists->cleanOutThreads();
    155152
    156     all_music->resetListings();
     153    gMusicData->all_music->resetListings();
    157154
    158     the_playlists->getActive()->removeAllWidgets();
     155    gMusicData->all_playlists->getActive()->removeAllWidgets();
    159156
    160157    if (class LCD * lcd = LCD::Get())
    161158        lcd->switchToTime();
     
    198195
    199196void DatabaseBox::keepFilling()
    200197{
    201     if (all_music->doneLoading() &&
    202         the_playlists->doneLoading())
     198    if (gMusicData->all_music->doneLoading() &&
     199        gMusicData->all_playlists->doneLoading())
    203200    {
    204201        //  Good, now lets grab some QListItems
    205         if (all_music->putYourselfOnTheListView(allmusic))
     202        if (gMusicData->all_music->putYourselfOnTheListView(allmusic))
    206203        {
    207204            allmusic->setText(tr("All My Music"));
    208205            fill_list_timer->stop();
    209             the_playlists->setActiveWidget(allcurrent);
    210             active_playlist = the_playlists->getActive();
     206            gMusicData->all_playlists->setActiveWidget(allcurrent);
     207            active_playlist = gMusicData->all_playlists->getActive();
    211208            active_playlist->putYourselfOnTheListView(allcurrent);
    212             the_playlists->showRelevantPlaylists(alllists);
     209            gMusicData->all_playlists->showRelevantPlaylists(alllists);
    213210            // XXX listview->ensureItemVisible(listview->currentItem());
    214211            checkTree();
    215212
     
    252249        return;
    253250    }
    254251
    255     if (the_playlists->nameIsUnique(active_pl_edit->text(), 0))
     252    if (gMusicData->all_playlists->nameIsUnique(active_pl_edit->text(), 0))
    256253    {
    257         the_playlists->copyNewPlaylist(active_pl_edit->text());
    258         the_playlists->showRelevantPlaylists(alllists);
     254        gMusicData->all_playlists->copyNewPlaylist(active_pl_edit->text());
     255        gMusicData->all_playlists->showRelevantPlaylists(alllists);
    259256        checkTree();
    260257        closeActivePopup();
    261258    }
     
    283280    {
    284281        if (rename_item->getID() < 0)
    285282        {
    286             if (the_playlists->nameIsUnique(playlist_rename->text(),
     283            if (gMusicData->all_playlists->nameIsUnique(playlist_rename->text(),
    287284                                            rename_item->getID() * -1))
    288285            {
    289                 the_playlists->renamePlaylist(rename_item->getID() * -1,
     286                gMusicData->all_playlists->renamePlaylist(rename_item->getID() * -1,
    290287                                              playlist_rename->text());
    291288                rename_item->setText(playlist_rename->text());
    292289                tree->Redraw();
     
    310307    if (!active_popup)
    311308        return;
    312309
    313     the_playlists->popBackPlaylist();
    314     the_playlists->showRelevantPlaylists(alllists);
     310    gMusicData->all_playlists->popBackPlaylist();
     311    gMusicData->all_playlists->showRelevantPlaylists(alllists);
    315312    checkTree();
    316313
    317314    closeActivePopup();
     
    324321
    325322    closeActivePopup();
    326323
    327     the_playlists->clearActive();
    328     the_playlists->showRelevantPlaylists(alllists);
     324    gMusicData->all_playlists->clearActive();
     325    gMusicData->all_playlists->showRelevantPlaylists(alllists);
    329326    checkTree();
    330327}
    331328
     
    462459            else if (check_item->prevSibling(1))
    463460                tree->MoveUp();
    464461
    465             the_playlists->deletePlaylist(check_item->getID() * -1);
    466             //the_playlists->showRelevantPlaylists(alllists);
     462            gMusicData->all_playlists->deletePlaylist(check_item->getID() * -1);
     463            //gMusicData->all_playlists->showRelevantPlaylists(alllists);
    467464            item->RemoveFromParent();
    468465            //delete item; will be deleted by generic tree
    469             the_playlists->refreshRelevantPlaylists(alllists);
     466            gMusicData->all_playlists->refreshRelevantPlaylists(alllists);
    470467            checkTree();
    471468            return;
    472469        }
     
    490487    {
    491488        if (check_item->getID() < 0)
    492489        {
    493             the_playlists->copyToActive(check_item->getID() * -1);
    494             the_playlists->refreshRelevantPlaylists(alllists);
     490            gMusicData->all_playlists->copyToActive(check_item->getID() * -1);
     491            gMusicData->all_playlists->refreshRelevantPlaylists(alllists);
    495492            tree->RefreshCurrentLevel();
    496493            checkTree();
    497494            // XXX listview->setCurrentItem(allcurrent);
     
    531528   
    532529        // Put on whatever all_music tells us is there
    533530   
    534         cditem->setText(all_music->getCDTitle());
     531        cditem->setText(gMusicData->all_music->getCDTitle());
    535532        cditem->setCheck(0);
    536533        cditem->setCheckable(false);
    537534
    538535        qApp->lock();
    539536
    540         all_music->putCDOnTheListView(cditem);
     537        gMusicData->all_music->putCDOnTheListView(cditem);
    541538       
    542539        //  reflect selections in cd playlist
    543540
     
    549546            if (CDCheckItem *track_ptr = dynamic_cast<CDCheckItem*>(uit))
    550547            {
    551548                track_ptr->setCheck(0);
    552                 if (the_playlists->checkCDTrack(track_ptr->getID() * -1))
     549                if (gMusicData->all_playlists->checkCDTrack(track_ptr->getID() * -1))
    553550                    track_ptr->setCheck(2);
    554551            }
    555552            ++it;
     
    624621        Metadata *mdata;
    625622        if (!cd)
    626623        {
    627             mdata = all_music->getMetadata(id);
     624            mdata = gMusicData->all_music->getMetadata(id);
    628625            if (!mdata)
    629626                return;
    630627        }
     
    632629        {
    633630            // Need to allocate storage for CD Metadata
    634631            mdata = new Metadata;
    635             if (!all_music->getCDMetadata(id, mdata))
     632            if (!gMusicData->all_music->getCDMetadata(id, mdata))
    636633            {
    637634                delete mdata;
    638635                return;
     
    925922
    926923    active_popup->ShowPopup(this, SLOT(closeActivePopup()));
    927924
    928     if (the_playlists->pendingWriteback())
     925    if (gMusicData->all_playlists->pendingWriteback())
    929926        pb->setEnabled(true);
    930927    else
    931928        pb->setEnabled(false);
     
    10681065        UIListGenericTree *item = (UIListGenericTree *)delete_item->getParent();
    10691066        if (TreeCheckItem *item_owner = dynamic_cast<TreeCheckItem*>(item))
    10701067        {
    1071             Playlist *owner = the_playlists->getPlaylist(item_owner->getID() *
     1068            Playlist *owner = gMusicData->all_playlists->getPlaylist(item_owner->getID() *
    10721069                                                         -1);
    10731070            owner->removeTrack(delete_item->getID(), true);
    10741071        }
     
    10831080                    "whatever you're trying to get rid of");
    10841081        }
    10851082
    1086         the_playlists->refreshRelevantPlaylists(alllists);
     1083        gMusicData->all_playlists->refreshRelevantPlaylists(alllists);
    10871084        checkTree();
    10881085    }
    10891086    else if (PlaylistTrack *delete_item = dynamic_cast<PlaylistTrack*>(item))
     
    10961093        UIListGenericTree *item = (UIListGenericTree *)delete_item->getParent();
    10971094        if (TreeCheckItem *item_owner = dynamic_cast<TreeCheckItem*>(item))
    10981095        {
    1099             Playlist *owner = the_playlists->getPlaylist(item_owner->getID() *
     1096            Playlist *owner = gMusicData->all_playlists->getPlaylist(item_owner->getID() *
    11001097                                                         -1);
    11011098            owner->removeTrack(delete_item->getID(), false);
    11021099        }
     
    11101107            VERBOSE(VB_IMPORTANT, "deleteTrack() - I don't know how to delete "
    11111108                    "whatever you're trying to get rid of");
    11121109        }
    1113         the_playlists->refreshRelevantPlaylists(alllists);
     1110        gMusicData->all_playlists->refreshRelevantPlaylists(alllists);
    11141111        checkTree();
    11151112    }
    11161113}
     
    12511248        cditem->setText(title);
    12521249}
    12531250
    1254 ReadCDThread::ReadCDThread(const QString &dev,
    1255                            PlaylistsContainer *all_the_playlists,
    1256                            AllMusic *all_the_music)
     1251ReadCDThread::ReadCDThread(const QString &dev)
    12571252{
    12581253    m_CDdevice = dev;
    1259     the_playlists = all_the_playlists;
    1260     all_music = all_the_music;
    12611254    cd_status_changed = false;
    12621255}
    12631256
     
    12721265
    12731266    bool redo = false;
    12741267
    1275     if (tracknum != all_music->getCDTrackCount())
     1268    if (tracknum != gMusicData->all_music->getCDTrackCount())
    12761269    {
    12771270        cd_status_changed = true;
    12781271        VERBOSE(VB_IMPORTANT, QString("CD status has changed."));
     
    12831276    if (tracknum == 0)
    12841277    {
    12851278        //  No CD, or no recognizable CD
    1286         all_music->clearCDData();
    1287         the_playlists->clearCDList();
     1279        gMusicData->all_music->clearCDData();
     1280        gMusicData->all_playlists->clearCDList();
    12881281    }
    12891282    else if (tracknum > 0)
    12901283    {
     
    12931286        Metadata *checker = decoder->getLastMetadata();
    12941287        if (checker)
    12951288        {
    1296             if (!all_music->checkCDTrack(checker))
     1289            if (!gMusicData->all_music->checkCDTrack(checker))
    12971290            {
    12981291                redo = true;
    12991292                cd_status_changed = true;
    1300                 all_music->clearCDData();
    1301                 the_playlists->clearCDList();
     1293                gMusicData->all_music->clearCDData();
     1294                gMusicData->all_playlists->clearCDList();
    13021295            }
    13031296            else
    13041297                cd_status_changed = false;
     
    13201313        Metadata *track = decoder->getMetadata(actual_tracknum);
    13211314        if (track)
    13221315        {
    1323             all_music->addCDTrack(track);
     1316            gMusicData->all_music->addCDTrack(track);
    13241317
    13251318            if (!setTitle)
    13261319            {
     
    13421335                    "    More likely, however, is that you need to delete\n"
    13431336                    "    ~/.cddb and ~/.cdserverrc and restart mythmusic.");
    13441337                }
    1345                 all_music->setCDTitle(parenttitle);
     1338                gMusicData->all_music->setCDTitle(parenttitle);
    13461339                setTitle = true;
    13471340            }
    13481341            delete track;
  • mythmusic/main.cpp

     
    2929#include "dbcheck.h"
    3030#include "importmusic.h"
    3131#include "filescanner.h"
     32#include "musicplayer.h"
    3233#include "config.h"
    3334
    3435// System header (relies on config.h define)
     
    141142    }
    142143}
    143144
    144 void startPlayback(PlaylistsContainer *all_playlists, AllMusic *all_music)
     145void startPlayback(void)
    145146{
    146147    PlaybackBoxMusic *pbb;
    147148    pbb = new PlaybackBoxMusic(gContext->GetMainWindow(),
    148                                "music_play", "music-", all_playlists,
    149                                all_music, chooseCD(), "music_playback");
     149                               "music_play", "music-", chooseCD(), "music_playback");
    150150    qApp->unlock();
    151151    pbb->exec();
    152152    qApp->lock();
    153153
    154     pbb->stop();
    155 
    156154    qApp->processEvents();
    157155
    158156    delete pbb;
    159157}
    160158
    161 void startDatabaseTree(PlaylistsContainer *all_playlists, AllMusic *all_music)
     159void startDatabaseTree(void)
    162160{
    163     DatabaseBox dbbox(all_playlists, all_music, gContext->GetMainWindow(),
     161    DatabaseBox dbbox(gContext->GetMainWindow(),
    164162                      chooseCD(), "music_select", "music-", "music database");
    165163    qApp->unlock();
    166164    dbbox.exec();
     
    195193    return false;
    196194}
    197195
    198 struct MusicData
     196void RebuildMusicTree(void)
    199197{
    200     QString paths;
    201     QString startdir;
    202     PlaylistsContainer *all_playlists;
    203     AllMusic *all_music;
    204     bool runPost;
    205 };
     198    if (!gMusicData->all_music || !gMusicData->all_playlists)
     199        return;
    206200
    207 void RebuildMusicTree(MusicData *mdata)
    208 {
    209201    MythBusyDialog *busy = new MythBusyDialog(
    210202        QObject::tr("Rebuilding music tree"));
    211203
    212204    busy->start();
    213     mdata->all_music->startLoading();
    214     while (!mdata->all_music->doneLoading())
     205    gMusicData->all_music->startLoading();
     206    while (!gMusicData->all_music->doneLoading())
    215207    {
    216208        qApp->processEvents();
    217209        usleep(50000);
    218210    }
    219     mdata->all_playlists->postLoad();
     211    gMusicData->all_playlists->postLoad();
    220212    busy->Close();
    221213    busy->deleteLater();
    222214}
    223215
    224 static void postMusic(MusicData *mdata);
     216static void postMusic(void);
    225217
    226218void MusicCallback(void *data, QString &selection)
    227219{
    228     MusicData *mdata = (MusicData *)data;
     220    (void) data;
    229221
    230222    QString sel = selection.lower();
    231 
    232223    if (sel == "music_create_playlist")
    233         startDatabaseTree(mdata->all_playlists, mdata->all_music);
     224        startDatabaseTree();
    234225    else if (sel == "music_play")
    235         startPlayback(mdata->all_playlists, mdata->all_music);
     226        startPlayback();
    236227    else if (sel == "music_rip")
    237228    {
    238229        if (startRipper())
     
    240231            // If startRipper returns true, then new data should be present
    241232
    242233            //  Tell the metadata to reset itself
    243             RebuildMusicTree(mdata);
     234            RebuildMusicTree();
    244235        }
    245236    }
    246237    else if (sel == "music_import")
    247238    {
    248239        if (startImport())
    249             RebuildMusicTree(mdata);
     240            RebuildMusicTree();
    250241    }
    251242    else if (sel == "settings_scan")
    252243    {
    253         if ("" != mdata->startdir)
     244        if ("" != gMusicData->startdir)
    254245        {
    255246            FileScanner *fscan = new FileScanner();
    256             fscan->SearchDir(mdata->startdir);
    257             RebuildMusicTree(mdata);
     247            fscan->SearchDir(gMusicData->startdir);
     248            RebuildMusicTree();
    258249        }
    259250    }
    260251    else if (sel == "music_set_general")
     
    274265    }
    275266    else if (sel == "exiting_menu")
    276267    {
    277         if (mdata)
     268        if (gMusicData)
    278269        {
    279             if (mdata->runPost)
    280                 postMusic(mdata);
    281             delete mdata;
     270            if (gMusicData->runPost)
     271                postMusic();
    282272        }
    283273    }
    284274}
    285275
    286 void runMenu(MusicData *mdata, QString which_menu)
     276void runMenu(QString which_menu)
    287277{
    288278    QString themedir = gContext->GetThemeDir();
    289279
     
    291281                                              GetMythMainWindow()->GetMainStack(),
    292282                                              "music menu");
    293283
    294     diag->setCallback(MusicCallback, mdata);
     284    diag->setCallback(MusicCallback, NULL);
    295285    diag->setKillable();
    296286
    297287    if (diag->foundTheme())
     
    313303void runMusicSelection(void);
    314304void runRipCD(void);
    315305void runScan(void);
     306void showMiniPlayer(void);
    316307
    317 
    318308void handleMedia(MythMediaDevice *cd)
    319309{
    320310    // Note that we should deal with other disks that may contain music.
     
    365355    REG_JUMP("Select music playlists", "", "", runMusicSelection);
    366356    REG_JUMP("Rip CD",                 "", "", runRipCD);
    367357    REG_JUMP("Scan music",             "", "", runScan);
     358    REG_JUMPEX("Show Miniplayer",        "", "", showMiniPlayer, false);
    368359
    369360    REG_KEY("Music", "DELETE",     "Delete track from playlist", "D");
    370361    REG_KEY("Music", "NEXTTRACK",  "Move to the next track",     ">,.,Z,End");
     
    423414
    424415    Decoder::SetLocationFormatUseTags();
    425416
     417    gPlayer = new MusicPlayer(NULL, chooseCD());
     418    gMusicData = new MusicData();
     419
    426420    return 0;
    427421}
    428422
    429 static void preMusic(MusicData *mdata)
     423static void preMusic()
    430424{
    431425    srand(time(NULL));
    432426
     
    474468    //  Load all playlists into RAM (once!)
    475469    PlaylistsContainer *all_playlists = new PlaylistsContainer(all_music, gContext->GetHostName());
    476470
    477     mdata->paths = paths;
    478     mdata->startdir = startdir;
    479     mdata->all_playlists = all_playlists;
    480     mdata->all_music = all_music;
     471    gMusicData->paths = paths;
     472    gMusicData->startdir = startdir;
     473    gMusicData->all_playlists = all_playlists;
     474    gMusicData->all_music = all_music;
    481475}
    482476
    483 static void postMusic(MusicData *mdata)
     477static void postMusic()
    484478{
    485479    // Automagically save all playlists and metadata (ratings) that have changed
    486     if (mdata->all_music->cleanOutThreads())
     480    if (gMusicData->all_music->cleanOutThreads())
    487481    {
    488         mdata->all_music->save();
     482        gMusicData->all_music->save();
    489483    }
    490484
    491     if (mdata->all_playlists->cleanOutThreads())
     485    if (gMusicData->all_playlists->cleanOutThreads())
    492486    {
    493         mdata->all_playlists->save();
    494         int x = mdata->all_playlists->getPending();
     487        gMusicData->all_playlists->save();
     488        int x = gMusicData->all_playlists->getPending();
    495489        SavePending(x);
    496490    }
    497491
    498     delete mdata->all_music;
    499     delete mdata->all_playlists;
     492    delete gMusicData->all_music;
     493    gMusicData->all_music = NULL;
     494    delete gMusicData->all_playlists;
     495    gMusicData->all_playlists = NULL;
    500496}
    501497
    502498int mythplugin_run(void)
    503499{
    504     MusicData *mdata = new MusicData();
    505     mdata->runPost = true;
     500    gMusicData->runPost = true;
    506501
    507     preMusic(mdata);
    508     runMenu(mdata, "musicmenu.xml");
     502    preMusic();
     503    runMenu("musicmenu.xml");
    509504
    510505    return 0;
    511506}
    512507
    513508int mythplugin_config(void)
    514509{
    515     MusicData *mdata = new MusicData();
    516     mdata->runPost = false;
    517     mdata->paths = gContext->GetSetting("TreeLevels");
    518     mdata->startdir = gContext->GetSetting("MusicLocation");
    519     mdata->startdir = QDir::cleanDirPath(mdata->startdir);
    520    
    521     if (!mdata->startdir.endsWith("/"))
    522         mdata->startdir += "/";
     510    gMusicData->runPost = false;
     511    gMusicData->paths = gContext->GetSetting("TreeLevels");
     512    gMusicData->startdir = gContext->GetSetting("MusicLocation");
     513    gMusicData->startdir = QDir::cleanDirPath(gMusicData->startdir);
    523514
    524     Metadata::SetStartdir(mdata->startdir);
     515    if (!gMusicData->startdir.endsWith("/"))
     516        gMusicData->startdir += "/";
    525517
     518    Metadata::SetStartdir(gMusicData->startdir);
     519
    526520    Decoder::SetLocationFormatUseTags();
    527521
    528     runMenu(mdata, "music_settings.xml");
     522    runMenu("music_settings.xml");
    529523
    530524    return 0;
    531525}
    532526
    533 void runMusicPlayback(void)
     527void mythplugin_destroy(void)
    534528{
    535     MusicData mdata;
     529    delete gPlayer;
     530    delete gMusicData;
     531}
    536532
     533void runMusicPlayback(void)
     534{
    537535    gContext->addCurrentLocation("playmusic");
    538     preMusic(&mdata);
    539     startPlayback(mdata.all_playlists, mdata.all_music);
    540     postMusic(&mdata);
     536    preMusic();
     537    startPlayback();
     538    postMusic();
    541539    gContext->removeCurrentLocation();
    542540}
    543541
    544542void runMusicSelection(void)
    545543{
    546     MusicData mdata;
    547 
    548544    gContext->addCurrentLocation("musicplaylists");
    549     preMusic(&mdata);
    550     startDatabaseTree(mdata.all_playlists, mdata.all_music);
    551     postMusic(&mdata);
     545    preMusic();
     546    startDatabaseTree();
     547    postMusic();
    552548    gContext->removeCurrentLocation();
    553549}
    554550
    555551void runRipCD(void)
    556552{
    557     MusicData mdata;
    558 
    559553    gContext->addCurrentLocation("ripcd");
    560     preMusic(&mdata);
     554    preMusic();
    561555    if (startRipper())
    562556    {
    563557        // if startRipper returns true, then new files should be present
    564558        // so we should look for them.
    565559        FileScanner *fscan = new FileScanner();
    566         fscan->SearchDir(mdata.startdir);
    567         RebuildMusicTree(&mdata);
     560        fscan->SearchDir(gMusicData->startdir);
     561        RebuildMusicTree();
    568562    }
    569     postMusic(&mdata);
     563    postMusic();
    570564    gContext->removeCurrentLocation();
    571565}
    572566
    573567void runScan(void)
    574568{
    575     MusicData mdata;
     569    preMusic();
    576570
    577     preMusic(&mdata);
    578 
    579     if ("" != mdata.startdir)
     571    if ("" != gMusicData->startdir)
    580572    {
    581573        FileScanner *fscan = new FileScanner();
    582         fscan->SearchDir(mdata.startdir);
    583         RebuildMusicTree(&mdata);
     574        fscan->SearchDir(gMusicData->startdir);
     575        RebuildMusicTree();
    584576    }
    585577
    586     postMusic(&mdata);
     578    postMusic();
    587579}
     580
     581void showMiniPlayer(void)
     582{
     583    // only show the miniplayer if there isn't already a client attached
     584    if (!gPlayer->hasClient())
     585        gPlayer->showMiniPlayer();
     586}
  • mythmusic/musicplayer.cpp

     
     1// ANSI C includes
     2#include <cstdlib>
     3
     4// C++ includes
     5#include <iostream>
     6
     7using namespace std;
     8
     9// qt
     10#include <qapplication.h>
     11#include <qurl.h>
     12#include <qwidget.h>
     13
     14// mythtv
     15#include <mythtv/mythcontext.h>
     16#include <mythtv/audiooutput.h>
     17#include <mythtv/mythdbcon.h>
     18
     19// mythmusic
     20#include "musicplayer.h"
     21#include "decoder.h"
     22#include "cddecoder.h"
     23#include "constants.h"
     24#include "mainvisual.h"
     25#include "miniplayer.h"
     26
     27MusicPlayer  *gPlayer = NULL;
     28
     29////////////////////////////////////////////////////////////////
     30
     31MusicPlayer::MusicPlayer(QObject *parent, const QString &dev)
     32    :QObject(parent)
     33{
     34    m_CDdevice = dev;
     35    m_decoder = NULL;
     36    m_input = NULL;
     37    m_output = NULL;
     38
     39    m_playlistTree = NULL;
     40    m_currentNode = NULL;
     41    m_currentMetadata = NULL;
     42
     43    m_listener = NULL;
     44    m_visual = NULL;
     45
     46    m_isAutoplay = false;
     47    m_isPlaying = false;
     48
     49    QString playmode = gContext->GetSetting("PlayMode", "none");
     50    if (playmode.lower() == "random")
     51        setShuffleMode(SHUFFLE_RANDOM);
     52    else if (playmode.lower() == "intelligent")
     53        setShuffleMode(SHUFFLE_INTELLIGENT);
     54    else if (playmode.lower() == "album")
     55        setShuffleMode(SHUFFLE_ALBUM);
     56    else if (playmode.lower() == "artist")
     57        setShuffleMode(SHUFFLE_ARTIST);
     58    else
     59        setShuffleMode(SHUFFLE_OFF);
     60
     61    QString repeatmode = gContext->GetSetting("RepeatMode", "all");
     62    if (repeatmode.lower() == "track")
     63        setRepeatMode(REPEAT_TRACK);
     64    else if (repeatmode.lower() == "all")
     65        setRepeatMode(REPEAT_ALL);
     66    else
     67        setRepeatMode(REPEAT_OFF);
     68
     69    QString resumestring = gContext->GetSetting("ResumeMode", "off");
     70    if (resumestring.lower() == "off")
     71        m_resumeMode = RESUME_OFF;
     72    else if (resumestring.lower() == "track")
     73        m_resumeMode = RESUME_TRACK;
     74    else
     75        m_resumeMode = RESUME_EXACT;
     76
     77    gContext->addListener(this);
     78}
     79
     80MusicPlayer::~MusicPlayer()
     81{
     82//    setListener(NULL);
     83//    setVisual(NULL);
     84
     85    if (!hasClient())
     86        savePosition();
     87
     88    gContext->removeListener(this);
     89
     90    stop(true);
     91
     92    if (m_playlistTree)
     93        delete m_playlistTree;
     94
     95    if (m_currentMetadata)
     96        delete m_currentMetadata;
     97    m_currentMetadata = NULL;
     98}
     99
     100void MusicPlayer::setListener(QObject *listener)
     101{
     102    if (m_listener && m_output)
     103        m_output->removeListener(m_listener);
     104
     105    if (m_listener && m_decoder)
     106        m_decoder->removeListener(m_listener);
     107
     108    m_listener = listener;
     109
     110    if (m_listener && m_output)
     111        m_output->addListener(m_listener);
     112
     113    if (m_listener && m_decoder)
     114        m_decoder->addListener(m_listener);
     115
     116    (listener == NULL) ? m_isAutoplay = true :  m_isAutoplay = false;
     117}
     118
     119void MusicPlayer::setVisual(MainVisual *visual)
     120{
     121    if (m_visual && m_output)
     122    {
     123        m_output->removeListener(m_visual);
     124        m_output->removeVisual(m_visual);
     125    }
     126
     127    m_visual = visual;
     128
     129    if (m_visual && m_output)
     130    {
     131        m_output->addListener(m_visual);
     132        m_output->addVisual(m_visual);
     133    }
     134}
     135
     136void MusicPlayer::playFile(const Metadata &meta)
     137{
     138    playFile(meta.Filename());
     139}
     140
     141void MusicPlayer::playFile(const QString &filename)
     142{
     143    m_currentFile = filename;
     144    play();
     145}
     146
     147void MusicPlayer::stop(bool stopAll)
     148{
     149    stopDecoder();
     150
     151    if (m_output)
     152    {
     153        if (m_output->GetPause())
     154        {
     155            pause();
     156        }
     157        m_output->Reset();
     158    }
     159
     160    if (m_input)
     161        delete m_input;
     162    m_input = NULL;
     163
     164    m_isPlaying = false;
     165
     166    if (stopAll && m_decoder)
     167    {
     168        m_decoder->removeListener(this);
     169        if (m_listener)
     170            m_decoder->removeListener(m_listener);
     171
     172        delete m_decoder;
     173        m_decoder = NULL;
     174        m_listener = NULL;
     175    }
     176
     177    if (stopAll && m_output)
     178    {
     179        m_output->removeListener(this);
     180        if (m_listener)
     181            m_output->removeListener(m_listener);
     182
     183        if (m_visual)
     184        {
     185            m_output->removeListener(m_visual);
     186            m_output->removeVisual(m_visual);
     187        }
     188        delete m_output;
     189        m_output = NULL;
     190        m_visual = NULL;
     191    }
     192}
     193
     194void MusicPlayer::pause(void)
     195{
     196    if (m_output)
     197    {
     198        m_isPlaying = !m_isPlaying;
     199        m_output->Pause(!m_isPlaying);
     200    }
     201    // wake up threads
     202    if (m_decoder)
     203    {
     204        m_decoder->lock();
     205        m_decoder->cond()->wakeAll();
     206        m_decoder->unlock();
     207    }
     208}
     209
     210void MusicPlayer::play(void)
     211{
     212    stopDecoder();
     213
     214    if (!m_output)
     215        openOutputDevice();
     216
     217    if (m_input)
     218        delete m_input;
     219
     220    m_input = new QFile(m_currentFile);
     221
     222    if (m_decoder && !m_decoder->factory()->supports(m_currentFile))
     223    {
     224        m_decoder->removeListener(this);
     225
     226        if (m_listener)
     227            m_decoder->removeListener(m_listener);
     228
     229        delete m_decoder;
     230        m_decoder = NULL;
     231    }
     232
     233    if (!m_decoder)
     234    {
     235        m_decoder = Decoder::create(m_currentFile, m_input, m_output, true);
     236        if (!m_decoder)
     237        {
     238            VERBOSE(VB_IMPORTANT, "MusicPlayer: Failed to create decoder for playback");
     239            return;
     240        }
     241
     242        if (m_currentFile.contains("cda") == 1)
     243            dynamic_cast<CdDecoder*>(m_decoder)->setDevice(m_CDdevice);
     244
     245        m_decoder->setBlockSize(2 * 1024);
     246
     247        m_decoder->addListener(this);
     248
     249        if (m_listener)
     250            m_decoder->addListener(m_listener);
     251    }
     252    else
     253    {
     254        m_decoder->setInput(m_input);
     255        m_decoder->setFilename(m_currentFile);
     256        m_decoder->setOutput(m_output);
     257    }
     258
     259    if (m_decoder->initialize())
     260    {
     261        if (m_output)
     262            m_output->Reset();
     263
     264        m_decoder->start();
     265
     266        m_isPlaying = true;
     267
     268        if (m_currentNode)
     269        {
     270            // FIXME this is ugly having to keep two metadata objects in sync
     271            if (m_currentNode->getInt() > 0)
     272            {
     273                m_currentMetadata = Metadata::getMetadataFromID(m_currentNode->getInt());
     274                if (m_currentMetadata)
     275                {
     276                    m_currentMetadata->incPlayCount();
     277                    m_currentMetadata->setLastPlay();
     278                }
     279                // if all_music is still in scope we need to keep that in sync
     280                if (gMusicData->all_music)
     281                {
     282                    Metadata *mdata = gMusicData->all_music->getMetadata(m_currentNode->getInt());
     283                    if (mdata)
     284                    {
     285                        mdata->incPlayCount();
     286                        mdata->setLastPlay();
     287                    }
     288                }
     289            }
     290            else
     291            {
     292                // CD track
     293                CdDecoder *cddecoder = dynamic_cast<CdDecoder*>(m_decoder);
     294                if (m_decoder)
     295                    m_currentMetadata = cddecoder->getMetadata(-m_currentNode->getInt());
     296            }
     297        }
     298    }
     299}
     300
     301void MusicPlayer::stopDecoder(void)
     302{
     303    if (m_decoder && m_decoder->running())
     304    {
     305        m_decoder->lock();
     306        m_decoder->stop();
     307        m_decoder->unlock();
     308    }
     309
     310    if (m_decoder)
     311    {
     312        m_decoder->lock();
     313        m_decoder->cond()->wakeAll();
     314        m_decoder->unlock();
     315    }
     316
     317    if (m_decoder)
     318        m_decoder->wait();
     319
     320    if (m_currentMetadata)
     321    {
     322        if (m_currentMetadata->hasChanged())
     323            m_currentMetadata->persist();
     324        delete m_currentMetadata;
     325    }
     326    m_currentMetadata = NULL;
     327}
     328
     329void MusicPlayer::openOutputDevice(void)
     330{
     331    QString adevice;
     332
     333    if (gContext->GetSetting("MusicAudioDevice") == "default")
     334        adevice = gContext->GetSetting("AudioOutputDevice");
     335    else
     336        adevice = gContext->GetSetting("MusicAudioDevice");
     337
     338    // TODO: Error checking that device is opened correctly!
     339    m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
     340                                    AUDIOOUTPUT_MUSIC, true, false);
     341    m_output->setBufferSize(256 * 1024);
     342    m_output->SetBlocking(false);
     343
     344    m_output->addListener(this);
     345
     346    if (m_listener)
     347        m_output->addListener(m_listener);
     348
     349    if (m_visual)
     350    {
     351        m_output->addListener((QObject*) m_visual);
     352        m_output->addVisual(m_visual);
     353    }
     354}
     355
     356void MusicPlayer::next(void)
     357{
     358    if (!m_currentNode)
     359        return;
     360
     361    GenericTree *node = m_currentNode->nextSibling(1, ((int) m_shuffleMode) + 1);
     362    if (node)
     363    {
     364        m_currentNode = node;
     365    }
     366    else
     367    {
     368        if (m_repeatMode == REPEAT_ALL)
     369        {
     370            // start playing again from first track
     371            GenericTree *parent = m_currentNode->getParent();
     372            if (parent)
     373            {
     374                node = parent->getChildAt(0, ((int) m_shuffleMode) + 1);
     375                if (node)
     376                    m_currentNode = node;
     377                else
     378                    return; // stop()
     379            }
     380        }
     381        else
     382            return; // stop()
     383    }
     384
     385    QString filename = getFilenameFromID(node->getInt());
     386    if (!filename.isEmpty())
     387        playFile(filename);
     388    else
     389        stop();
     390}
     391
     392void MusicPlayer::previous(void)
     393{
     394    if (!m_currentNode)
     395        return;
     396
     397    GenericTree *node = m_currentNode->prevSibling(1, ((int) m_shuffleMode) + 1);
     398    if (node)
     399    {
     400        m_currentNode = node;
     401        QString filename = getFilenameFromID(node->getInt());
     402        if (!filename.isEmpty())
     403            playFile(filename);
     404        else
     405            return;//stop();
     406    }
     407    else
     408    {
     409        // FIXME take repeat mode into account
     410        return; //stop();
     411    }
     412}
     413
     414void MusicPlayer::nextAuto(void)
     415{
     416    if (!m_isAutoplay)
     417        return;
     418
     419    if (!m_currentNode)
     420        return;
     421
     422    if (m_repeatMode == REPEAT_TRACK)
     423    {
     424        play();
     425        return;
     426    }
     427    else
     428        next();
     429
     430    MiniPlayer *popup = new MiniPlayer(gContext->GetMainWindow(), this);
     431    popup->showPlayer(10);
     432    popup->deleteLater();
     433    popup = NULL;
     434}
     435
     436void MusicPlayer::customEvent(QCustomEvent *event)
     437{
     438    if (m_isAutoplay)
     439    {
     440        switch ((int)event->type())
     441        {
     442            case OutputEvent::Error:
     443            {
     444                OutputEvent *aoe = (OutputEvent *) event;
     445
     446                VERBOSE(VB_IMPORTANT, QString("Output Error - %1")
     447                        .arg(*aoe->errorMessage()));
     448                MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     449                        "Output Error:",
     450                        QString("MythMusic has encountered the following error:\n%1")
     451                                .arg(*aoe->errorMessage()));
     452                stop(true);
     453
     454                break;
     455            }
     456
     457            case DecoderEvent::Finished:
     458            {
     459                nextAuto();
     460                break;
     461            }
     462
     463            case DecoderEvent::Error:
     464            {
     465                stop(true);
     466
     467                QApplication::sendPostedEvents();
     468
     469                DecoderEvent *dxe = (DecoderEvent *) event;
     470
     471                VERBOSE(VB_IMPORTANT, QString("Decoder Error - %1")
     472                        .arg(*dxe->errorMessage()));
     473                MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     474                                        "Decoder Error",
     475                                        QString("MythMusic has encountered the following error:\n%1")
     476                                        .arg(*dxe->errorMessage()));
     477                break;
     478            }
     479
     480            case MythEvent::MythEventMessage:
     481            {
     482                MythEvent *me = (MythEvent *) event;
     483                cout << "Got MythEvent: " << me->Message() << endl;
     484                if (me->Message().left(14) == "PLAYBACK_START")
     485                {
     486                    QString hostname = me->Message().mid(15);
     487                    if (hostname == gContext->GetHostName())
     488                    {
     489                        savePosition();
     490                        stop(true);
     491                    }
     492                }
     493
     494                if (me->Message().left(12) == "PLAYBACK_END")
     495                {
     496                    QString hostname = me->Message().mid(13);
     497                    if (hostname == gContext->GetHostName())
     498                    {
     499                        play();
     500                        seek(gContext->GetNumSetting("MusicBookmarkPosition", 0));
     501                        gContext->SaveSetting("MusicBookmark", "");
     502                        gContext->SaveSetting("MusicBookmarkPosition", 0);
     503                    }
     504                }
     505                break;
     506            }
     507        }
     508    }
     509
     510
     511    if ((int)event->type() == OutputEvent::Info)
     512    {
     513        OutputEvent *oe = (OutputEvent *) event;
     514        m_currentTime = oe->elapsedSeconds();
     515    }
     516
     517    QObject::customEvent(event);
     518}
     519
     520QString MusicPlayer::getFilenameFromID(int id)
     521{
     522    QString filename = "";
     523
     524    if (id > 0)
     525    {
     526        QString aquery = "SELECT CONCAT_WS('/', "
     527                        "music_directories.path, music_songs.filename) AS filename "
     528                        "FROM music_songs "
     529                        "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
     530                        "WHERE music_songs.song_id = :ID";
     531
     532        MSqlQuery query(MSqlQuery::InitCon());
     533        query.prepare(aquery);
     534        query.bindValue(":ID", id);
     535        if (!query.exec() || query.numRowsAffected() < 1)
     536            MythContext::DBError("get filename", query);
     537
     538        if (query.isActive() && query.size() > 0)
     539        {
     540            query.first();
     541            filename = QString::fromUtf8(query.value(0).toString());
     542            if (!filename.contains("://"))
     543                filename = Metadata::GetStartdir() + filename;
     544        }
     545    }
     546    else
     547    {
     548        // cd track
     549        CdDecoder *cddecoder = dynamic_cast<CdDecoder*>(m_decoder);
     550        if (m_decoder)
     551        {
     552            Metadata *meta = cddecoder->getMetadata(-id);
     553            if (meta)
     554                filename = meta->Filename();
     555        }
     556    }
     557    return filename;
     558}
     559
     560QString MusicPlayer::getRouteToCurrent(void)
     561{
     562    QStringList route;
     563
     564    if (m_currentNode)
     565    {
     566        GenericTree *climber = m_currentNode;
     567
     568        route.push_front(QString::number(climber->getInt()));
     569        while((climber = climber->getParent()))
     570        {
     571            route.push_front(QString::number(climber->getInt()));
     572        }
     573    }
     574    return route.join(",");
     575}
     576
     577void MusicPlayer::savePosition(void)
     578{
     579    if (m_resumeMode != RESUME_OFF)
     580    {
     581        gContext->SaveSetting("MusicBookmark", getRouteToCurrent());
     582        if (m_resumeMode == RESUME_EXACT)
     583            gContext->SaveSetting("MusicBookmarkPosition", m_currentTime);
     584    }
     585}
     586
     587void MusicPlayer::seek(int pos)
     588{
     589    if (m_output)
     590    {
     591        m_output->Reset();
     592        m_output->SetTimecode(pos*1000);
     593
     594        if (m_decoder && m_decoder->running())
     595        {
     596            m_decoder->lock();
     597            m_decoder->seek(pos);
     598            m_decoder->unlock();
     599        }
     600    }
     601}
     602
     603void MusicPlayer::showMiniPlayer(void)
     604{
     605    MiniPlayer *popup = new MiniPlayer(gContext->GetMainWindow(), this);
     606    popup->exec();
     607    popup->deleteLater();
     608    popup = NULL;
     609}
     610
     611Metadata *MusicPlayer::getCurrentMetadata(void)
     612{
     613    if (!m_currentNode)
     614        return NULL;
     615
     616    if (m_currentMetadata)
     617        return m_currentMetadata;
     618
     619    m_currentMetadata = Metadata::getMetadataFromID(m_currentNode->getInt());
     620
     621    return m_currentMetadata;
     622}
     623
     624void MusicPlayer::refreshMetadata(void)
     625{
     626    if (m_currentMetadata)
     627    {
     628        delete m_currentMetadata;
     629        m_currentMetadata = NULL;
     630    }
     631
     632    getCurrentMetadata();
     633}
     634
     635MusicPlayer::RepeatMode MusicPlayer::toggleRepeatMode(void)
     636{
     637    switch (m_repeatMode)
     638    {
     639        case REPEAT_OFF:
     640            m_repeatMode = REPEAT_TRACK;
     641            break;
     642        case REPEAT_TRACK:
     643            m_repeatMode = REPEAT_ALL;
     644            break;
     645        case REPEAT_ALL:
     646            m_repeatMode = REPEAT_OFF;
     647           break;
     648        default:
     649            m_repeatMode = REPEAT_OFF;
     650            break;
     651    }
     652
     653    return m_repeatMode;
     654}
     655
     656MusicPlayer::ShuffleMode MusicPlayer::toggleShuffleMode(void)
     657{
     658    switch (m_shuffleMode)
     659    {
     660        case SHUFFLE_OFF:
     661            m_shuffleMode = SHUFFLE_RANDOM;
     662            break;
     663        case SHUFFLE_RANDOM:
     664            m_shuffleMode = SHUFFLE_INTELLIGENT;
     665            break;
     666        case SHUFFLE_INTELLIGENT:
     667            m_shuffleMode = SHUFFLE_ALBUM;
     668           break;
     669        case SHUFFLE_ALBUM:
     670            m_shuffleMode = SHUFFLE_ARTIST;
     671           break;
     672        case SHUFFLE_ARTIST:
     673            m_shuffleMode = SHUFFLE_OFF;
     674           break;
     675        default:
     676            m_shuffleMode = SHUFFLE_OFF;
     677            break;
     678    }
     679
     680    return m_shuffleMode;
     681}
  • mythmusic/playbackbox.h

     
    11#ifndef PLAYBACKBOX_H_
    22#define PLAYBACKBOX_H_
    33
     4// qt
    45#include <qtimer.h>
    56#include <qmutex.h>
    67#include <qvaluevector.h>
    78
     9// mythtv
    810#include <mythtv/mythwidgets.h>
    911#include <mythtv/dialogbox.h>
    1012#include <mythtv/audiooutput.h>
    1113
     14// mythmusic
    1215#include "mainvisual.h"
    1316#include "metadata.h"
    1417#include "playlist.h"
    1518#include "editmetadata.h"
    1619#include "databasebox.h"
     20#include "musicplayer.h"
    1721
    1822class Output;
    1923class Decoder;
     
    2832
    2933    PlaybackBoxMusic(MythMainWindow *parent, QString window_name,
    3034                     QString theme_filename,
    31                      PlaylistsContainer *the_playlists, AllMusic *the_music,
    3235                     const QString &cd_device, const char *name = 0);
    3336
    3437    ~PlaybackBoxMusic(void);
    3538
    36     void closeEvent(QCloseEvent *);
    3739    void customEvent(QCustomEvent *);
    38     void showEvent(QShowEvent *);
    3940    void keyPressEvent(QKeyEvent *e);
    4041    void constructPlaylistTree();
    4142
     
    4445  public slots:
    4546
    4647    void play();
    47     void pause();
    4848    void stop();
     49    void pause();
    4950    void stopDecoder();
    5051    void previous();
    5152    void next();
     
    5354    void seekback();
    5455    void seek(int);
    5556    void stopAll();
    56     void setShuffleMode(unsigned int mode);
     57    void setShuffleMode(MusicPlayer::ShuffleMode mode);
    5758    void toggleShuffle();
    5859    void increaseRating();
    5960    void decreaseRating();
    60     void setRepeatMode(unsigned int mode);
     61    void setRepeatMode(MusicPlayer::RepeatMode mode);
    6162    void toggleRepeat();
    6263    void editPlaylist();
    6364    void nextAuto();
     
    109110    void updatePlaylistFromCD(void);
    110111    void setTrackOnLCD(Metadata *mdata);
    111112    void updateTrackInfo(Metadata *mdata);
    112     void openOutputDevice(void);
    113113    void postUpdate();
    114114    void playFirstTrack();
    115115    void bannerEnable(QString text, int millis);
    116116    void bannerEnable(Metadata *mdata, bool fullScreen = false);
    117117    void bannerToggle(Metadata *mdata);
    118118    void savePosition(uint position);
    119     void restorePosition(void);
     119    void restorePosition(const QString &position);
    120120    void pushButton(UIPushButtonType *button);
    121121    QString getTimeString(int exTime, int maxTime);
    122122
    123     QIODevice *input;
    124     AudioOutput *output;
    125     Decoder *decoder;
    126 
    127123    QString playfile;
    128124    QString statusString;
    129125    QString curSmartPlaylistCategory;
    130126    QString curSmartPlaylistName;
    131127
    132     enum RepeatMode
    133     { REPEAT_OFF = 0,
    134       REPEAT_TRACK,
    135       REPEAT_ALL,
    136       MAX_REPEAT_MODES
    137     };
    138     enum ShuffleMode
    139     { SHUFFLE_OFF = 0,
    140       SHUFFLE_RANDOM,
    141       SHUFFLE_INTELLIGENT,
    142       SHUFFLE_ALBUM,
    143       SHUFFLE_ARTIST,
    144       MAX_SHUFFLE_MODES
    145     };
    146     enum ResumeMode
    147     { RESUME_OFF,
    148       RESUME_TRACK,
    149       RESUME_EXACT,
    150       MAX_RESUME_MODES
    151     };
    152 
    153128    bool listAsShuffled;
    154129    int outputBufferSize;
    155130    int currentTime, maxTime;
     
    158133
    159134    Metadata *curMeta;
    160135
    161 
    162     unsigned int shufflemode;
    163     unsigned int repeatmode;
    164136    unsigned int resumemode;
    165137
    166     bool isplaying;
    167 
    168138    bool menufilters;
    169139
    170140    ReadCDThread *cd_reader_thread;
     
    189159    bool tree_is_done;
    190160    bool first_playlist_check;
    191161
    192     AllMusic *all_music;
    193     PlaylistsContainer *all_playlists;
    194 
    195162    QTimer  *waiting_for_playlists_timer;
    196163    QTimer  *volume_display_timer;
    197164
    198     GenericTree *playlist_tree;
    199 
    200165    bool cycle_visualizer;
    201166    bool random_visualizer;
    202167    bool show_album_art;
  • mythmusic/mainvisual.cpp

     
    217217
    218218    VisualNode *node = 0;
    219219
    220     if (playing && output()) {
     220    if (playing && output())
     221    {
    221222        long synctime = output()->GetAudiotime();
    222223        mutex()->lock();
    223224        VisualNode *prev = 0;
    224         while ((node = nodes.first())) {
     225        while ((node = nodes.first()))
     226        {
    225227            if (node->offset > synctime)
    226228                break;
    227 
    228229            delete prev;
    229230            nodes.removeFirst();
    230231            prev = node;
    231232        }
    232233        mutex()->unlock();
    233         node = prev; 
     234        node = prev;
    234235    }
    235236
    236237    bool stop = TRUE;
     
    276277    switch (event->type())
    277278    {
    278279        case OutputEvent::Playing:
    279         playing = TRUE;
    280         // fall through intended
    281 
    282280        case OutputEvent::Info:
    283281        case OutputEvent::Buffering:
    284282        case OutputEvent::Paused:
     283            playing = TRUE;
     284
    285285            if (! timer->isActive())
    286286                timer->start(1000 / fps);
    287 
    288287            break;
    289288
    290289        case OutputEvent::Stopped:
  • mythmusic/miniplayer.h

     
     1#ifndef MINIPLAYER_H_
     2#define MINIPLAYER_H_
     3
     4#include <qstring.h>
     5
     6#include "mythtv/mythdialogs.h"
     7
     8class MusicPlayer;
     9class QTimer;
     10class Metadata;
     11
     12/// Preferred position to place popup miniplayer.
     13enum PlayerPosition
     14{
     15    MP_POSTOPDIALOG,
     16    MP_POSBOTTOMDIALOG,
     17    MP_POSCENTERDIALOG
     18};
     19
     20class MPUBLIC MiniPlayer : public MythThemedDialog
     21{
     22  Q_OBJECT
     23
     24  public:
     25    MiniPlayer(MythMainWindow *parent,
     26                    MusicPlayer *parentPlayer,
     27                    const char *name = 0,
     28                    bool setsize = true);
     29    ~MiniPlayer();
     30
     31  public slots:
     32    virtual void show();
     33    virtual void hide();
     34    void timerTimeout(void);
     35    void showPlayer(int showTime);
     36    void showInfoTimeout(void);
     37
     38  protected:
     39    virtual void keyPressEvent(QKeyEvent *e);
     40    virtual void customEvent(QCustomEvent *event);
     41
     42  private:
     43    void    wireupTheme(void);
     44    QString getTimeString(int exTime, int maxTime);
     45    void    updateTrackInfo(Metadata *mdata);
     46    void    seekforward(void);
     47    void    seekback(void);
     48    void    seek(int pos);
     49    void    increaseRating(void);
     50    void    decreaseRating(void);
     51    void    showShuffleMode(void);
     52    void    showRepeatMode(void);
     53    void    showVolume(void);
     54
     55    int           m_currTime, m_maxTime;
     56
     57    MusicPlayer  *m_parentPlayer;
     58    int           m_popupWidth;
     59    int           m_popupHeight;
     60
     61    QTimer       *m_displayTimer;
     62    QTimer       *m_infoTimer;
     63
     64    bool          m_showingInfo;
     65
     66    UITextType   *m_titleText;
     67    UITextType   *m_artistText;
     68    UITextType   *m_albumText;
     69    UITextType   *m_timeText;
     70    UITextType   *m_infoText;
     71    UIImageType  *m_coverImage;
     72
     73    UITextType   *m_shufflestateText;
     74    UITextType   *m_repeatstateText;
     75
     76    UIRepeatedImageType *m_ratingsImage;
     77};
     78
     79#endif