Ticket #4222: 4222-v1.patch

File 4222-v1.patch, 68.6 KB (added by paulh, 12 years ago)

Patch to allow MythMusic to play in the background

  • mythmusic/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,
    3233                                   QString theme_filename,
     
    3738                : MythThemedDialog(parent, window_name, theme_filename, name)
    3839{
    3940    //  A few internal variable defaults
    40  
    41     input = NULL;
    42     output = NULL;
    43     decoder = NULL;
    4441    mainvisual = NULL;
    4542    visual_mode_timer = NULL;
    4643    lcd_update_timer = NULL;
    4744    waiting_for_playlists_timer = NULL;
    4845    speed_scroll_timer = NULL;
    49     playlist_tree = NULL;
    5046    playlist_popup = NULL;
    5147    progress = NULL;
    5248
    53     isplaying = false;
     49    gPlayer->setListener(this);
     50
    5451    tree_is_done = false;
    5552    first_playlist_check = true;
    5653    outputBufferSize = 256;
     
    112109                this, SLOT(hideVolume()));
    113110    }
    114111
    115     // Figure out the shuffle mode
     112    setShuffleMode(gPlayer->getShuffleMode());
    116113
    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);
    128 
    129114    QString resumestring = gContext->GetSetting("ResumeMode", "off");
    130115    if (resumestring.lower() == "off")
    131116        resumemode = RESUME_OFF;
     
    134119    else
    135120        resumemode = RESUME_EXACT;
    136121
    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);
     122    setRepeatMode(gPlayer->getRepeatMode());
    144123
    145124    // Set some button values
    146125
     
    196175        mainvisual->setGeometry(screenwidth + 10, screenheight + 10, 160, 160);
    197176    mainvisual->show();
    198177
     178    gPlayer->setVisual(mainvisual);
     179
    199180    fullscreen_blank = false;
    200181
    201182    visual_modes = QStringList::split(';', gContext->GetSetting("VisualMode"));
     
    240221{
    241222    savePosition(currentTime);
    242223
    243     stopAll();
    244 
    245     if (output)
    246     {
    247         delete output;
    248         output = NULL;
    249     }
    250 
    251224    if (progress)
    252225    {
    253226        progress->Close();
     
    262235        delete cd_reader_thread;
    263236    }
    264237
    265     if (playlist_tree)
    266         delete playlist_tree;
    267 
    268     if (shufflemode == SHUFFLE_INTELLIGENT)
     238    MusicPlayer::ShuffleMode shufflemode = gPlayer->getShuffleMode();
     239    if (shufflemode == MusicPlayer::SHUFFLE_INTELLIGENT)
    269240        gContext->SaveSetting("PlayMode", "intelligent");
    270     else if (shufflemode == SHUFFLE_RANDOM)
     241    else if (shufflemode == MusicPlayer::SHUFFLE_RANDOM)
    271242        gContext->SaveSetting("PlayMode", "random");
    272     else if (shufflemode == SHUFFLE_ALBUM)
     243    else if (shufflemode == MusicPlayer::SHUFFLE_ALBUM)
    273244        gContext->SaveSetting("PlayMode", "album");
    274     else if (shufflemode == SHUFFLE_ARTIST)
     245    else if (shufflemode == MusicPlayer::SHUFFLE_ARTIST)
    275246        gContext->SaveSetting("PlayMode", "artist");
    276247    else
    277248        gContext->SaveSetting("PlayMode", "none");
    278249
    279     if (repeatmode == REPEAT_TRACK)
     250    MusicPlayer::RepeatMode repeatmode = gPlayer->getRepeatMode();
     251    if (repeatmode == MusicPlayer::REPEAT_TRACK)
    280252        gContext->SaveSetting("RepeatMode", "track");
    281     else if (repeatmode == REPEAT_ALL)
     253    else if (repeatmode == MusicPlayer::REPEAT_ALL)
    282254        gContext->SaveSetting("RepeatMode", "all");
    283255    else
    284256        gContext->SaveSetting("RepeatMode", "none");
     257
    285258    if (class LCD *lcd = LCD::Get())
    286259        lcd->switchToTime();
    287260}
     
    304277    resetTimer();
    305278
    306279    QStringList actions;
    307     gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions);
     280    gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions, false);
    308281
    309282    int scrollAmt = 1;
    310283
     
    343316        }
    344317        else if (action == "PAUSE")
    345318        {
    346             if (isplaying)
     319            if (gPlayer->isPlaying())
    347320            {
    348321                if (pause_button)
    349322                    pause_button->push();
     
    371344                stop_button->push();
    372345            else
    373346                stop();
    374 
    375347            currentTime = 0;
    376348        }
    377349        else if (action == "THMBUP")
     
    427399                bannerToggle(curMeta);
    428400            else
    429401                showEditMetadataDialog();
     402        else if (action == "ESCAPE" && visualizer_status != 2)
     403        {
     404            DialogBox *dialog = new DialogBox(gContext->GetMainWindow(),
     405                             tr("Exiting Music Player\n"
     406                             "Do you want to continue playing in the background?"));
     407            dialog->AddButton("No - Exit, Stop Playing");
     408            dialog->AddButton("Yes - Exit, Continue Playing");
     409            dialog->AddButton("Cancel");
     410            int res = dialog->exec();
     411            dialog->deleteLater();
     412
     413            if (res == kDialogCodeButton0)
     414            {
     415                stopAll();
     416                done(kDialogCodeAccepted);
     417            }
     418            else if (res == kDialogCodeButton1)
     419            {
     420                gPlayer->setListener(NULL);
     421                gPlayer->setVisual(NULL);
     422                done(kDialogCodeAccepted);
     423            }
     424            else
     425                handled = true;
     426        }
    430427        else
    431428            handled = false;
    432429    }
     
    541538                music_tree_list->incSearchStart();
    542539            else if (action == "INCSEARCHNEXT")
    543540                music_tree_list->incSearchNext();
    544             else
    545                 handled = false;
    546541        }
    547542    }
    548543    else
     
    565560                handled = false;
    566561        }
    567562    }
    568 
    569     if (!handled)
    570         MythThemedDialog::keyPressEvent(e);
    571563}
    572564
    573565void PlaybackBoxMusic::handlePush(QString buttonname)
     
    10621054        GenericTree *node = music_tree_list->getCurrentNode();
    10631055        curMeta = all_music->getMetadata(node->getInt());
    10641056
    1065         setShuffleMode(shufflemode);
     1057        setShuffleMode(gPlayer->getShuffleMode());
    10661058
    10671059        music_tree_list->refresh();
    10681060
     
    11041096                branches_to_current_node.append(1); //  We're on a playlist (not "My Music")
    11051097                branches_to_current_node.append(0); //  Active play Queue
    11061098
    1107                 if (resumemode > RESUME_OFF)
    1108                     restorePosition();
     1099                if (gPlayer->isPlaying())
     1100                {
     1101                    restorePosition(gPlayer->getRouteToCurrent());
     1102                }
    11091103                else
    1110                     music_tree_list->moveToNodesFirstChild(branches_to_current_node);
     1104                {
     1105                    if (resumemode > RESUME_OFF)
     1106                        restorePosition(gContext->GetSetting("MusicBookmark", ""));
     1107                    else
     1108                        music_tree_list->moveToNodesFirstChild(branches_to_current_node);
     1109                }
    11111110
    11121111                music_tree_list->refresh();
    11131112                if (show_whole_tree)
     
    11621161
    11631162void PlaybackBoxMusic::changeVolume(bool up_or_down)
    11641163{
    1165     if (volume_control && output)
     1164    if (volume_control && gPlayer->getOutput())
    11661165    {
    11671166        if (up_or_down)
    1168             output->AdjustCurrentVolume(2);
     1167            gPlayer->getOutput()->AdjustCurrentVolume(2);
    11691168        else
    1170             output->AdjustCurrentVolume(-2);
     1169            gPlayer->getOutput()->AdjustCurrentVolume(-2);
    11711170        showVolume(true);
    11721171    }
    11731172}
    11741173
    11751174void PlaybackBoxMusic::toggleMute()
    11761175{
    1177     if (volume_control && output)
     1176    if (volume_control && gPlayer->getOutput())
    11781177    {
    1179         output->ToggleMute();
     1178        gPlayer->getOutput()->ToggleMute();
    11801179        showVolume(true);
    11811180    }
    11821181}
     
    11841183void PlaybackBoxMusic::showProgressBar()
    11851184{
    11861185
    1187     if (progress_bar) {
    1188 
     1186    if (progress_bar)
     1187    {
    11891188             progress_bar->SetTotal(maxTime);
    11901189             progress_bar->SetUsed(currentTime);
    11911190    }
     
    11941193void PlaybackBoxMusic::showVolume(bool on_or_off)
    11951194{
    11961195    float volume_level;
    1197     if (volume_control && output)
     1196    if (volume_control && gPlayer->getOutput())
    11981197    {
    11991198        if (volume_status)
    12001199        {
    12011200            if (on_or_off)
    12021201            {
    1203                 volume_status->SetUsed(output->GetCurrentVolume());
     1202                volume_status->SetUsed(gPlayer->getOutput()->GetCurrentVolume());
    12041203                volume_status->SetOrder(0);
    12051204                volume_status->refresh();
    12061205                volume_display_timer->changeInterval(2000);
    12071206                if (class LCD *lcd = LCD::Get())
    12081207                    lcd->switchToVolume("Music");
    12091208
    1210                 if (output->GetMute())
     1209                if (gPlayer->getOutput()->GetMute())
    12111210                    volume_level = 0.0;
    12121211                else
    1213                     volume_level = (float)output->GetCurrentVolume() /
     1212                    volume_level = (float)gPlayer->getOutput()->GetCurrentVolume() /
    12141213                                   (float)100;
    12151214
    12161215                if (class LCD *lcd = LCD::Get())
     
    12391238
    12401239void PlaybackBoxMusic::play()
    12411240{
     1241    if (gPlayer->isPlaying())
     1242        gPlayer->stop();
    12421243
    1243     if (isplaying)
    1244         stop();
    1245 
    12461244    if (curMeta)
    12471245        playfile = curMeta->Filename();
    12481246    else
     
    12521250        return;
    12531251    }
    12541252
    1255     QUrl sourceurl(playfile);
    1256     QString sourcename(playfile);
    1257 
    1258     if (!output)
    1259         openOutputDevice();
    1260 
    1261     if (output->GetPause())
     1253    if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
    12621254    {
    1263         pause();
     1255        gPlayer->pause();
    12641256        return;
    12651257    }
    12661258
    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     }
     1259    gPlayer->setCurrentNode(music_tree_list->getCurrentNode());
     1260    gPlayer->playFile(playfile);
    12811261
    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 
    13051262    currentTime = 0;
    13061263
    1307     mainvisual->setDecoder(decoder);
    1308     mainvisual->setOutput(output);
     1264    mainvisual->setDecoder(gPlayer->getDecoder());
     1265    mainvisual->setOutput(gPlayer->getOutput());
    13091266    mainvisual->setMetadata(curMeta);
    13101267
    1311     if (decoder->initialize())
     1268    if (!gPlayer->isPlaying())
    13121269    {
    1313         if (output)
     1270        if (resumemode == RESUME_EXACT &&
     1271                gContext->GetNumSetting("MusicBookmarkPosition", 0) > 0)
    13141272        {
    1315             output->Reset();
    1316         }
    1317 
    1318         decoder->start();
    1319 
    1320         if (resumemode == RESUME_EXACT && gContext->GetNumSetting("MusicBookmarkPosition", 0) > 0)
    1321         {
    13221273            seek(gContext->GetNumSetting("MusicBookmarkPosition", 0));
    13231274            gContext->SaveSetting("MusicBookmarkPosition", 0);
    13241275        }
    1325 
    1326         bannerEnable(curMeta, show_album_art);
    1327         isplaying = true;
    1328         curMeta->setLastPlay();
    1329         curMeta->incPlayCount();
    13301276    }
     1277
     1278    bannerEnable(curMeta, show_album_art);
    13311279}
    13321280
    13331281void PlaybackBoxMusic::visEnable()
    13341282{
    1335     if (!visualizer_status != 2 && isplaying)
     1283    if (!visualizer_status != 2 && gPlayer->isPlaying())
    13361284    {
    13371285        setUpdatesEnabled(false);
    13381286        mainvisual->setGeometry(0, 0, screenwidth, screenheight);
     
    14101358void PlaybackBoxMusic::setTrackOnLCD(Metadata *mdata)
    14111359{
    14121360    LCD *lcd = LCD::Get();
    1413     if (!lcd)
     1361    if (!lcd || !mdata)
    14141362        return;
    14151363
    14161364    // Set the Artist and Tract on the LCD
     
    14211369
    14221370void PlaybackBoxMusic::pause(void)
    14231371{
    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 
     1372    gPlayer->pause();
    14371373}
    14381374
    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 
    14551375void PlaybackBoxMusic::stop(void)
    14561376{
    1457     stopDecoder();
     1377    gPlayer->stop();
    14581378
    1459     if (output)
    1460     {
    1461         if (output->GetPause())
    1462         {
    1463             pause();
    1464         }
    1465         output->Reset();
    1466     }
    1467 
    14681379    mainvisual->setDecoder(0);
    14691380    mainvisual->setOutput(0);
    14701381    mainvisual->deleteMetadata();
    14711382
    1472     delete input;
    1473     input = 0;
    1474 
    14751383    QString time_string = getTimeString(maxTime, 0);
    14761384
    14771385    if (time_text)
    14781386        time_text->SetText(time_string);
    14791387    if (info_text)
    14801388        info_text->SetText("");
    1481 
    1482     isplaying = false;
    14831389}
    14841390
    14851391void PlaybackBoxMusic::stopAll()
     
    14891395        lcd->switchToTime();
    14901396    }
    14911397
    1492     stop();
     1398    mainvisual->setDecoder(0);
     1399    mainvisual->setOutput(0);
     1400    mainvisual->deleteMetadata();
    14931401
    1494     if (decoder)
    1495     {
    1496         decoder->removeListener(this);
    1497         decoder = 0;
    1498     }
     1402    gPlayer->stop(true);
    14991403}
    15001404
    15011405void PlaybackBoxMusic::previous()
    15021406{
    1503     if (repeatmode == REPEAT_ALL)
     1407    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
    15041408    {
    15051409        if (music_tree_list->prevActive(true, show_whole_tree))
    15061410            music_tree_list->activate();
     
    15171421
    15181422void PlaybackBoxMusic::next()
    15191423{
    1520     if (repeatmode == REPEAT_ALL)
     1424    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
    15211425    {
    15221426        // Grab the next track after this one. First flag is to wrap around
    15231427        // to the beginning of the list. Second decides if we will traverse up
     
    15411445
    15421446void PlaybackBoxMusic::nextAuto()
    15431447{
    1544     stopDecoder();
    1545 
    1546     isplaying = false;
    1547 
    1548     if (repeatmode == REPEAT_TRACK)
     1448    if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_TRACK)
    15491449        play();
    15501450    else
    15511451        next();
     
    15691469
    15701470void PlaybackBoxMusic::seek(int pos)
    15711471{
    1572     if (output)
     1472    if (gPlayer->getOutput())
    15731473    {
    1574         output->Reset();
    1575         output->SetTimecode(pos*1000);
     1474        gPlayer->getOutput()->Reset();
     1475        gPlayer->getOutput()->SetTimecode(pos*1000);
    15761476
    1577         if (decoder && decoder->running())
     1477        if (gPlayer->getDecoder() && gPlayer->getDecoder()->running())
    15781478        {
    1579             decoder->lock();
    1580             decoder->seek(pos);
     1479            gPlayer->getDecoder()->lock();
     1480            gPlayer->getDecoder()->seek(pos);
    15811481
    15821482            if (mainvisual)
    15831483            {
     
    15861486                mainvisual->mutex()->unlock();
    15871487            }
    15881488
    1589             decoder->unlock();
     1489            gPlayer->getDecoder()->unlock();
    15901490        }
    15911491
    1592         if (!isplaying)
     1492        if (!gPlayer->isPlaying())
    15931493        {
    15941494            currentTime = pos;
    15951495            if (time_text)
     
    16141514    }
    16151515}
    16161516
    1617 void PlaybackBoxMusic::setShuffleMode(unsigned int mode)
     1517void PlaybackBoxMusic::setShuffleMode(MusicPlayer::ShuffleMode mode)
    16181518{
    1619     shufflemode = mode;
     1519    MusicPlayer::ShuffleMode shufflemode = mode;
    16201520    QString state;
    16211521
    16221522    switch (shufflemode)
    16231523    {
    1624         case SHUFFLE_INTELLIGENT:
     1524        case MusicPlayer::SHUFFLE_INTELLIGENT:
    16251525            state = tr("Smart");
    16261526            if (class LCD *lcd = LCD::Get())
    16271527                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_SMART);
    16281528            break;
    1629         case SHUFFLE_RANDOM:
     1529        case MusicPlayer::SHUFFLE_RANDOM:
    16301530            state = tr("Rand");
    16311531            if (class LCD *lcd = LCD::Get())
    16321532                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_RAND);
    16331533            break;
    1634         case SHUFFLE_ALBUM:
     1534        case MusicPlayer::SHUFFLE_ALBUM:
    16351535            state = tr("Album");
    16361536            if (class LCD *lcd = LCD::Get())
    16371537                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ALBUM);
    16381538            break;
    1639         case SHUFFLE_ARTIST:
     1539        case MusicPlayer::SHUFFLE_ARTIST:
    16401540            state = tr("Artist");
    16411541            if (class LCD *lcd = LCD::Get())
    16421542                lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ARTIST);
     
    16631563
    16641564    bannerEnable(QString("%1: %2").arg(tr("Shuffle")).arg(state), 4000);
    16651565
    1666     if (!shufflemode == SHUFFLE_OFF)
     1566    if (!shufflemode == MusicPlayer::SHUFFLE_OFF)
    16671567        music_tree_list->scrambleParents(true);
    16681568    else
    16691569        music_tree_list->scrambleParents(true);
     
    16751575        music_tree_list->setVisualOrdering(1);
    16761576    music_tree_list->refresh();
    16771577
    1678     if (isplaying)
     1578    if (gPlayer->isPlaying())
    16791579        setTrackOnLCD(curMeta);
    16801580}
    16811581
    16821582void PlaybackBoxMusic::toggleShuffle(void)
    16831583{
    1684     setShuffleMode(++shufflemode % MAX_SHUFFLE_MODES);
     1584    setShuffleMode(gPlayer->toggleShuffleMode());
    16851585}
    16861586
    16871587void PlaybackBoxMusic::increaseRating()
     
    17131613    }
    17141614}
    17151615
    1716 void PlaybackBoxMusic::setRepeatMode(unsigned int mode)
     1616void PlaybackBoxMusic::setRepeatMode(MusicPlayer::RepeatMode mode)
    17171617{
    1718     repeatmode = mode;
     1618    MusicPlayer::RepeatMode repeatmode = mode;
    17191619    QString state;
    17201620
    17211621    switch (repeatmode)
    17221622    {
    1723         case REPEAT_ALL:
     1623        case MusicPlayer::REPEAT_ALL:
    17241624            state = tr("All");
    17251625            if (class LCD *lcd = LCD::Get())
    17261626                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
    17271627            break;
    1728         case REPEAT_TRACK:
     1628        case MusicPlayer::REPEAT_TRACK:
    17291629            state = tr("Track");
    17301630            if (class LCD *lcd = LCD::Get())
    17311631                lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
     
    17871687    gContext->SaveSetting("MusicBookmarkPosition", position);
    17881688}
    17891689
    1790 void PlaybackBoxMusic::restorePosition()
     1690void PlaybackBoxMusic::restorePosition(const QString &position)
    17911691{
    17921692    QValueList <int> branches_to_current_node;
    1793     QString s = gContext->GetSetting("MusicBookmark", "");
    17941693
    1795     if (s != "")
     1694    if (position != "")
    17961695    {
    1797         QStringList list = QStringList::split(",", s);
     1696        QStringList list = QStringList::split(",", position);
    17981697
    17991698        for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
    18001699            branches_to_current_node.append((*it).toInt());
     
    18101709            {
    18111710                if (music_tree_list->tryToSetActive(branches_to_current_node))
    18121711                {
    1813                     music_tree_list->select();
     1712                    if (gPlayer->isPlaying())
     1713                    {
     1714                        GenericTree *node = music_tree_list->getCurrentNode();
     1715                        if (node)
     1716                        {
     1717                            curMeta = all_music->getMetadata(node->getInt());
     1718                            updateTrackInfo(curMeta);
     1719
     1720                            maxTime = curMeta->Length() / 1000;
     1721
     1722                            QString time_string = getTimeString(maxTime, 0);
     1723
     1724                            if (showrating)
     1725                            {
     1726                                if (ratings_image)
     1727                                    ratings_image->setRepeat(curMeta->Rating());
     1728                            }
     1729
     1730                            mainvisual->setDecoder(gPlayer->getDecoder());
     1731                            mainvisual->setOutput(gPlayer->getOutput());
     1732                            mainvisual->setMetadata(curMeta);
     1733                            bannerEnable(curMeta, show_album_art);
     1734                        }
     1735                    }
     1736                    else
     1737                        music_tree_list->select();
    18141738                    return;
    18151739                }
    18161740            }
     
    18201744            //we're in show all tree mode - try to restore the position
    18211745            if (music_tree_list->tryToSetActive(branches_to_current_node))
    18221746            {
    1823                 music_tree_list->select();
     1747                    if (gPlayer->isPlaying())
     1748                    {
     1749                        GenericTree *node = music_tree_list->getCurrentNode();
     1750                        if (node)
     1751                        {
     1752                            curMeta = all_music->getMetadata(node->getInt());
     1753                            updateTrackInfo(curMeta);
     1754
     1755                            maxTime = curMeta->Length() / 1000;
     1756
     1757                            QString time_string = getTimeString(maxTime, 0);
     1758
     1759                            if (showrating)
     1760                            {
     1761                                if (ratings_image)
     1762                                    ratings_image->setRepeat(curMeta->Rating());
     1763                            }
     1764
     1765                            mainvisual->setDecoder(gPlayer->getDecoder());
     1766                            mainvisual->setOutput(gPlayer->getOutput());
     1767                            mainvisual->setMetadata(curMeta);
     1768                            bannerEnable(curMeta, show_album_art);
     1769                        }
     1770                    }
     1771                    else
     1772                        music_tree_list->select();
    18241773                return;
    18251774            }
    18261775        }
     
    18351784
    18361785void PlaybackBoxMusic::toggleRepeat()
    18371786{
    1838     setRepeatMode(++repeatmode % MAX_REPEAT_MODES);
     1787    setRepeatMode(gPlayer->toggleRepeatMode());
    18391788}
    18401789
    18411790void PlaybackBoxMusic::constructPlaylistTree()
    18421791{
     1792    GenericTree *playlist_tree = gPlayer->getPlaylistTree();
     1793
    18431794    if (playlist_tree)
    18441795        delete playlist_tree;
    18451796
     
    19191870        cd_watcher->start(1000);
    19201871}
    19211872
    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 
    19351873void PlaybackBoxMusic::customEvent(QCustomEvent *event)
    19361874{
    19371875    switch ((int)event->type())
     
    20611999            break;
    20622000        }
    20632001    }
     2002    //cout << "status string: " << statusString << endl;
    20642003
    20652004    QWidget::customEvent(event);
    20662005}
     
    20952034    setTrackOnLCD(mdata);
    20962035}
    20972036
    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 
    21182037void PlaybackBoxMusic::handleTreeListSignals(int node_int, IntVector *attributes)
    21192038{
    21202039    if (attributes->size() < 4)
     
    21642083                ratings_image->setRepeat(curMeta->Rating());
    21652084        }
    21662085
    2167         if (output && output->GetPause())
    2168             stop();
    2169 
     2086        if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
     2087        {
     2088            gPlayer->stop();
     2089        }
    21702090        if (m_pushedButton && m_pushedButton->Name() == "play_button")
    21712091        {
    21722092            // Play button already pushed, so don't push it again.
     
    23492269
    23502270    // only give the user a choice of the track to play if shuffle mode is off
    23512271    MythComboBox *playCombo = NULL;
    2352     if (shufflemode == SHUFFLE_OFF)
     2272    if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
    23532273    {
    23542274        playCombo = new MythComboBox(false, popup, "play_combo" );
    23552275        playCombo->insertItem(tr("Continue playing current track"));
     
    23582278        playCombo->setBackgroundOrigin(ParentOrigin);
    23592279        popup->addWidget(playCombo);
    23602280    }
    2361    
     2281
    23622282    MythCheckBox *dupsCheck = new MythCheckBox(popup);
    23632283    dupsCheck->setText(tr("Remove Duplicates"));
    23642284    dupsCheck->setChecked(false);
     
    23882308
    23892309    // if shuffle mode != SHUFFLE_OFF we always try to continue playing
    23902310    // the current track
    2391     if (shufflemode == SHUFFLE_OFF)
     2311    if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
    23922312    {
    23932313        switch (playCombo->currentItem())
    23942314        {
  • mythmusic/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/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    wireupTheme();
     34
     35    gPlayer->setListener(this);
     36
     37    if (gPlayer->isPlaying() && gPlayer->getCurrentMetadata())
     38    {
     39        m_maxTime = gPlayer->getCurrentMetadata()->Length() / 1000;
     40        updateTrackInfo(gPlayer->getCurrentMetadata());
     41    }
     42}
     43
     44MiniPlayer::~MiniPlayer(void)
     45{
     46    gPlayer->setListener(NULL);
     47
     48    m_displayTimer->deleteLater();
     49    m_displayTimer = NULL;
     50
     51    if (class LCD *lcd = LCD::Get())
     52        lcd->switchToTime ();
     53}
     54
     55void MiniPlayer::showPlayer(int showTime)
     56{
     57    m_displayTimer->start(showTime * 1000, true);
     58    exec();
     59}
     60
     61void MiniPlayer::timerTimeout(void)
     62{
     63    done(Accepted);
     64}
     65
     66void MiniPlayer::wireupTheme(void)
     67{
     68    QString theme_file = QString("music-");
     69
     70    if (!loadThemedWindow("miniplayer", theme_file))
     71    {
     72        VERBOSE(VB_GENERAL, "MiniPlayer: cannot load theme!");
     73        done(0);
     74        return;
     75    }
     76
     77    // get dialog size from player_container area
     78    LayerSet *container = getContainer("player_container");
     79
     80    if (!container)
     81    {
     82        cerr << "MiniPlayer: cannot find the 'player_container'"
     83                " in your theme" << endl;
     84        done(0);
     85        return;
     86    }
     87
     88    m_popupWidth = container->GetAreaRect().width();
     89    m_popupHeight = container->GetAreaRect().height();
     90    setFixedSize(QSize(m_popupWidth, m_popupHeight));
     91
     92    int xbase, width, ybase, height;
     93    float wmult, hmult;
     94    gContext->GetScreenSettings(xbase, width, wmult, ybase, height, hmult);
     95    QRect tlwg = QRect(0, 0, width, height);
     96
     97    QPoint newpos;
     98
     99    PlayerPosition preferredPos = MP_POSTOPDIALOG;
     100
     101    if (preferredPos == MP_POSTOPDIALOG)
     102    {
     103        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2, 5);
     104        this->move(newpos);
     105    }
     106    else if (preferredPos == MP_POSBOTTOMDIALOG)
     107    {
     108        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
     109                        tlwg.height() - 5 - m_popupHeight);
     110        this->move(newpos);
     111    }
     112    else if (preferredPos == MP_POSCENTERDIALOG)
     113    {
     114        newpos = QPoint(tlwg.width() / 2 - m_popupWidth / 2,
     115                        tlwg.height() / 2 - m_popupHeight / 2);
     116        this->move(newpos);
     117    }
     118
     119    m_titleText = getUITextType("title_text");
     120    m_artistText = getUITextType("artist_text");
     121    m_timeText = getUITextType("time_text");
     122    m_infoText = getUITextType("info_text");
     123    m_albumText = getUITextType("album_text");
     124    m_ratingsImage = getUIRepeatedImageType("ratings_image");
     125    m_coverImage = getUIImageType("cover_image");
     126}
     127
     128void MiniPlayer::show()
     129{
     130    grabKeyboard();
     131
     132    MythDialog::show();
     133}
     134
     135void MiniPlayer::hide()
     136{
     137    releaseKeyboard();
     138
     139    MythDialog::hide();
     140}
     141
     142void MiniPlayer::keyPressEvent(QKeyEvent *e)
     143{
     144    bool handled = false;
     145    QStringList actions;
     146    if (gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions, false))
     147    {
     148        for (unsigned int i = 0; i < actions.size() && !handled; i++)
     149        {
     150            QString action = actions[i];
     151            handled = true;
     152            if (action == "ESCAPE")
     153                done(0);
     154            else if (action == "SELECT")
     155                    m_displayTimer->stop();
     156            else if (action == "NEXTTRACK")
     157            {
     158                gPlayer->next();
     159            }
     160            else if (action == "PREVTRACK")
     161            {
     162                gPlayer->previous();
     163            }
     164            else if (action == "FFWD")
     165            {
     166                seekforward();
     167            }
     168            else if (action == "RWND")
     169            {
     170                seekback();
     171            }
     172            else if (action == "PAUSE")
     173            {
     174                if (gPlayer->isPlaying())
     175                    gPlayer->pause();
     176                else
     177                {
     178                    if (gPlayer->isPlaying())
     179                        gPlayer->stop();
     180
     181                    if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
     182                    {
     183                        gPlayer->pause();
     184                        return;
     185                    }
     186
     187                    gPlayer->play();
     188                }
     189            }
     190            else if (action == "STOP")
     191            {
     192                gPlayer->stop();
     193
     194                QString time_string = getTimeString(m_maxTime, 0);
     195
     196                if (m_timeText)
     197                    m_timeText->SetText(time_string);
     198                if (m_infoText)
     199                    m_infoText->SetText("");
     200            }
     201            else if (action == "VOLUMEDOWN")
     202            {
     203                if (gPlayer->getOutput())
     204                    gPlayer->getOutput()->AdjustCurrentVolume(2);
     205            }
     206            else if (action == "VOLUMEUP")
     207            {
     208                if (gPlayer->getOutput())
     209                    gPlayer->getOutput()->AdjustCurrentVolume(-2);
     210            }
     211            else if (action == "MUTE")
     212            {
     213                if (gPlayer->getOutput())
     214                    gPlayer->getOutput()->ToggleMute();
     215            }
     216            else if (action == "THMBUP")
     217                increaseRating();
     218            else if (action == "THMBDOWN")
     219                decreaseRating();
     220            else
     221                handled = false;
     222        }
     223    }
     224}
     225
     226void MiniPlayer::customEvent(QCustomEvent *event)
     227{
     228
     229    switch ((int)event->type())
     230    {
     231        case OutputEvent::Playing:
     232        {
     233            if (gPlayer->getCurrentMetadata())
     234            {
     235                m_maxTime = gPlayer->getCurrentMetadata()->Length() / 1000;
     236                updateTrackInfo(gPlayer->getCurrentMetadata());
     237            }
     238            break;
     239        }
     240
     241        case OutputEvent::Buffering:
     242        {
     243            break;
     244        }
     245
     246        case OutputEvent::Paused:
     247        {
     248            break;
     249        }
     250
     251        case OutputEvent::Info:
     252       {
     253            OutputEvent *oe = (OutputEvent *) event;
     254
     255            int rs;
     256            m_currTime = rs = oe->elapsedSeconds();
     257
     258            QString time_string = getTimeString(rs, m_maxTime);
     259
     260            QString info_string;
     261
     262            //  Hack around for cd bitrates
     263            if (oe->bitrate() < 2000)
     264            {
     265                info_string.sprintf("%d "+tr("kbps")+ "   %.1f "+ tr("kHz")+ "   %s "+ tr("ch"),
     266                                   oe->bitrate(), float(oe->frequency()) / 1000.0,
     267                                   oe->channels() > 1 ? "2" : "1");
     268            }
     269            else
     270            {
     271                info_string.sprintf("%.1f "+ tr("kHz")+ "   %s "+ tr("ch"),
     272                                   float(oe->frequency()) / 1000.0,
     273                                   oe->channels() > 1 ? "2" : "1");
     274            }
     275
     276            if (m_timeText)
     277                m_timeText->SetText(time_string);
     278            if (m_infoText)
     279                m_infoText->SetText(info_string);
     280
     281            if (gPlayer->getCurrentMetadata())
     282            {
     283                if (class LCD *lcd = LCD::Get())
     284                {
     285                    float percent_heard = m_maxTime <=0 ? 0.0 :
     286                            ((float)rs / (float)gPlayer->getCurrentMetadata()->Length()) * 1000.0;
     287
     288                    QString lcd_time_string = time_string;
     289
     290                    // if the string is longer than the LCD width, remove all spaces
     291                    if (time_string.length() > lcd->getLCDWidth())
     292                        lcd_time_string.remove(' ');
     293
     294                    lcd->setMusicProgress(lcd_time_string, percent_heard);
     295                }
     296            }
     297            break;
     298        }
     299        case OutputEvent::Error:
     300        {
     301            break;
     302        }
     303        case DecoderEvent::Stopped:
     304        {
     305            break;
     306        }
     307        case DecoderEvent::Finished:
     308        {
     309            if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_TRACK)
     310               gPlayer->play();
     311            else
     312                gPlayer->next();
     313            break;
     314        }
     315        case DecoderEvent::Error:
     316        {
     317            break;
     318        }
     319    }
     320    QObject::customEvent(event);
     321}
     322
     323QString MiniPlayer::getTimeString(int exTime, int maxTime)
     324{
     325    QString time_string;
     326
     327    int eh = exTime / 3600;
     328    int em = (exTime / 60) % 60;
     329    int es = exTime % 60;
     330
     331    int maxh = maxTime / 3600;
     332    int maxm = (maxTime / 60) % 60;
     333    int maxs = maxTime % 60;
     334
     335    if (maxTime <= 0)
     336    {
     337        if (eh > 0)
     338            time_string.sprintf("%d:%02d:%02d", eh, em, es);
     339        else
     340            time_string.sprintf("%02d:%02d", em, es);
     341    }
     342    else
     343    {
     344        if (maxh > 0)
     345            time_string.sprintf("%d:%02d:%02d / %02d:%02d:%02d", eh, em,
     346                    es, maxh, maxm, maxs);
     347        else
     348            time_string.sprintf("%02d:%02d / %02d:%02d", em, es, maxm,
     349                    maxs);
     350    }
     351
     352    return time_string;
     353}
     354
     355void MiniPlayer::updateTrackInfo(Metadata *mdata)
     356{
     357    if (m_titleText)
     358        m_titleText->SetText(mdata->FormatTitle());
     359    if (m_artistText)
     360        m_artistText->SetText(mdata->FormatArtist());
     361    if (m_albumText)
     362        m_albumText->SetText(mdata->Album());
     363    if (m_ratingsImage)
     364        m_ratingsImage->setRepeat(mdata->Rating());
     365
     366    if (m_coverImage)
     367    {
     368        QImage image = gPlayer->getCurrentMetadata()->getAlbumArt(IT_FRONTCOVER);
     369        if (!image.isNull())
     370            m_coverImage->SetImage(
     371                    QPixmap(image.smoothScale(m_coverImage->GetSize(true))));
     372        m_coverImage->refresh();
     373    }
     374
     375    LCD *lcd = LCD::Get();
     376    if (lcd)
     377    {
     378        // Set the Artist and Track on the LCD
     379        lcd->switchToMusic(mdata->Artist(),
     380                       mdata->Album(),
     381                       mdata->Title());
     382    }
     383}
     384
     385void MiniPlayer::seekforward(void)
     386{
     387    int nextTime = m_currTime + 5;
     388    if (nextTime > m_maxTime)
     389        nextTime = m_maxTime;
     390    seek(nextTime);
     391}
     392
     393void MiniPlayer::seekback(void)
     394{
     395    int nextTime = m_currTime - 5;
     396    if (nextTime < 0)
     397        nextTime = 0;
     398    seek(nextTime);
     399}
     400
     401void MiniPlayer::seek(int pos)
     402{
     403    if (gPlayer->getOutput())
     404    {
     405        gPlayer->getOutput()->Reset();
     406        gPlayer->getOutput()->SetTimecode(pos*1000);
     407
     408        if (gPlayer->getDecoder() && gPlayer->getDecoder()->running())
     409        {
     410            gPlayer->getDecoder()->lock();
     411            gPlayer->getDecoder()->seek(pos);
     412            gPlayer->getDecoder()->unlock();
     413        }
     414
     415        if (!gPlayer->isPlaying())
     416        {
     417            m_currTime = pos;
     418            if (m_timeText)
     419                m_timeText->SetText(getTimeString(pos, m_maxTime));
     420
     421            //showProgressBar();
     422
     423            if (class LCD *lcd = LCD::Get())
     424            {
     425                float percent_heard = m_maxTime <= 0 ? 0.0 : ((float)pos /
     426                                      (float)m_maxTime);
     427
     428                QString lcd_time_string = getTimeString(pos, m_maxTime);
     429
     430                // if the string is longer than the LCD width, remove all spaces
     431                if (lcd_time_string.length() > lcd->getLCDWidth())
     432                    lcd_time_string.remove(' ');
     433
     434                lcd->setMusicProgress(lcd_time_string, percent_heard);
     435            }
     436        }
     437    }
     438}
     439
     440void MiniPlayer::increaseRating(void)
     441{
     442    Metadata *curMeta = gPlayer->getCurrentMetadata();
     443
     444    if (!curMeta)
     445        return;
     446
     447    if (m_ratingsImage)
     448    {
     449        curMeta->incRating();
     450        m_ratingsImage->setRepeat(curMeta->Rating());
     451    }
     452}
     453
     454void MiniPlayer::decreaseRating(void)
     455{
     456    Metadata *curMeta = gPlayer->getCurrentMetadata();
     457
     458    if (!curMeta)
     459        return;
     460
     461    if (m_ratingsImage)
     462    {
     463        curMeta->decRating();
     464        m_ratingsImage->setRepeat(curMeta->Rating());
     465    }
     466}
  • mythmusic/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        </image>
     1826
     1827        <textarea name="title_text" draworder="1" align="left">
     1828            <font>currenttitle</font>
     1829            <area>160,15,415,34</area>
     1830            <cutdown>yes</cutdown>
     1831        </textarea>
     1832
     1833        <textarea name="artist_text" draworder="1" align="left">
     1834            <font>currentartist</font>
     1835            <area>160,50,415,25</area>
     1836            <cutdown>yes</cutdown>
     1837        </textarea>
     1838
     1839        <textarea name="album_text" draworder="1" align="left">
     1840            <font>currentartist</font>
     1841            <area>160,73,415,25</area>
     1842            <cutdown>yes</cutdown>
     1843        </textarea>
     1844
     1845        <repeatedimage name="ratings_image" draworder="1" fleximage="no">
     1846            <filename>mm_rating.png</filename>
     1847            <position>160,105</position>
     1848            <orientation>LeftToRight</orientation>
     1849        </repeatedimage>
     1850
     1851        <textarea name="info_text" draworder="1" align="left">
     1852            <font>infotext</font>
     1853            <area>160,129,250,25</area>
     1854        </textarea>
     1855
     1856        <textarea name="time_text" draworder="1" align="right">
     1857            <font>currentartist</font>
     1858            <area>375,125,185,25</area>
     1859        </textarea>
     1860
     1861        <image name="cover_image" draworder="2">
     1862            <filename>mm_nothumb.png</filename>
     1863            <position>22,22</position>
     1864            <staticsize>122,124</staticsize>
     1865        </image>
     1866
     1867    </container>
     1868
     1869  </window>
     1870
    17951871</mythuitheme>
  • mythmusic/mythmusic/metadata.cpp

     
    725725    return image;
    726726}
    727727
     728// static function to get a matadata object given a track id
     729// it's upto the caller to delete the returned object when finished
     730Metadata *Metadata::getMetadataFromID(int id)
     731{
     732    Metadata *meta = NULL;
     733
     734    QString aquery = "SELECT music_songs.song_id, music_artists.artist_name, music_comp_artists.artist_name AS compilation_artist, "
     735                     "music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
     736                     "music_songs.track, music_songs.length, CONCAT_WS('/', "
     737                     "music_directories.path, music_songs.filename) AS filename, "
     738                     "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_albums.compilation, "
     739                     "music_songs.format "
     740                     "FROM music_songs "
     741                     "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
     742                     "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
     743                     "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
     744                     "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
     745                     "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
     746                     "WHERE music_songs.song_id = :TRACKID;";
     747
     748    QString filename, artist, album, title;
     749
     750    MSqlQuery query(MSqlQuery::InitCon());
     751    query.prepare(aquery);
     752    query.bindValue(":TRACKID", id);
     753    query.exec();
     754
     755    if (query.isActive() && query.size() > 0)
     756    {
     757        query.next();
     758        filename = QString::fromUtf8(query.value(9).toString());
     759        if (!filename.contains("://"))
     760            filename = m_startdir + filename;
     761
     762        artist = QString::fromUtf8(query.value(1).toString());
     763        if (artist.isEmpty())
     764            artist = QObject::tr("Unknown Artist");
     765
     766        album = QString::fromUtf8(query.value(3).toString());
     767        if (album.isEmpty())
     768            album = QObject::tr("Unknown Album");
     769
     770        title = QString::fromUtf8(query.value(4).toString());
     771        if (title.isEmpty())
     772            title = QObject::tr("Unknown Title");
     773
     774        meta = new Metadata(
     775            filename,
     776            artist,
     777            QString::fromUtf8(query.value(2).toString()),
     778            album,
     779            title,
     780            QString::fromUtf8(query.value(5).toString()),
     781            query.value(6).toInt(),
     782            query.value(7).toInt(),
     783            query.value(8).toInt(),
     784            query.value(0).toInt(),
     785            query.value(10).toInt(), //rating
     786            query.value(11).toInt(), //playcount
     787            query.value(12).toString(), //lastplay
     788            (query.value(13).toInt() > 0), //compilation
     789            query.value(14).toString()); //format
     790    }
     791    else
     792    {
     793         VERBOSE(VB_IMPORTANT, QString("Track %1 not found!!").arg(id));
     794         return NULL;
     795    }
     796
     797    return meta;
     798}
     799
     800//--------------------------------------------------------------------------
     801
    728802MetadataLoadingThread::MetadataLoadingThread(AllMusic *parent_ptr)
    729803{
    730804    parent = parent_ptr;
  • mythmusic/mythmusic/metadata.h

     
    183183    static QString GetStartdir() { return m_startdir; }
    184184
    185185    static QStringList fillFieldList(QString field);
     186    static Metadata *getMetadataFromID(int id);
    186187
    187188    QImage getAlbumArt(ImageType type);
    188189
  • mythmusic/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
     33    void mute(void) {};
     34    void unMute(void) {};
     35    void setVolume(void) {};
     36
     37    void play(void);
     38    void stop(bool stopAll = false);
     39    void pause(void);
     40    void next(void);
     41    void previous(void);
     42
     43    void nextAuto(void);
     44
     45    bool isPlaying(void) { return m_isPlaying; }
     46    bool hasClient(void) { return (m_listener != NULL); }
     47
     48    Decoder     *getDecoder(void) { return m_decoder; }
     49    AudioOutput *getOutput(void) { return m_output; }
     50
     51    GenericTree *getPlaylistTree() { return m_playlistTree; }
     52    void         setCurrentNode(GenericTree *node) { m_currentNode = node; }
     53    QString      getRouteToCurrent(void);
     54
     55    Metadata    *getCurrentMetadata(void);
     56
     57    void showMiniPlayer(void);
     58
     59    enum RepeatMode
     60    { REPEAT_OFF = 0,
     61      REPEAT_TRACK,
     62      REPEAT_ALL,
     63      MAX_REPEAT_MODES
     64    };
     65    enum ShuffleMode
     66    { SHUFFLE_OFF = 0,
     67      SHUFFLE_RANDOM,
     68      SHUFFLE_INTELLIGENT,
     69      SHUFFLE_ALBUM,
     70      SHUFFLE_ARTIST,
     71      MAX_SHUFFLE_MODES
     72    };
     73
     74    RepeatMode getRepeatMode(void) { return m_repeatMode; }
     75    void       setRepeatMode(RepeatMode mode) { m_repeatMode = mode; }
     76    RepeatMode toggleRepeatMode(void);
     77
     78    ShuffleMode getShuffleMode(void) { return m_shuffleMode; }
     79    void        setShuffleMode(ShuffleMode mode) { m_shuffleMode = mode; }
     80    ShuffleMode toggleShuffleMode(void);
     81
     82  protected:
     83    void customEvent(QCustomEvent *event);
     84
     85  private:
     86    void stopDecoder(void);
     87    void openOutputDevice(void);
     88    QString getFilenameFromID(int id);
     89
     90    GenericTree *m_playlistTree;
     91
     92    GenericTree *m_currentNode;
     93    Metadata    *m_currentMetadata;
     94    QString      m_currentFile;
     95
     96    QIODevice   *m_input;
     97    AudioOutput *m_output;
     98    Decoder     *m_decoder;
     99
     100    QObject     *m_listener;
     101    MainVisual  *m_visual;
     102
     103    QString      m_CDdevice;
     104
     105    bool         m_isPlaying;
     106    bool         m_isAutoplay;
     107
     108    ShuffleMode  m_shuffleMode;
     109    RepeatMode   m_repeatMode;
     110};
     111
     112// This global variable contains the MusicPlayer instance for the application
     113extern MPUBLIC MusicPlayer *gPlayer;
     114
     115#endif
  • mythmusic/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)
     
    151152    pbb->exec();
    152153    qApp->lock();
    153154
    154     pbb->stop();
    155 
    156155    qApp->processEvents();
    157156
    158157    delete pbb;
     
    313312void runMusicSelection(void);
    314313void runRipCD(void);
    315314void runScan(void);
     315void showMiniPlayer(void);
    316316
    317 
    318317void handleMedia(MythMediaDevice *cd)
    319318{
    320319    // Note that we should deal with other disks that may contain music.
     
    365364    REG_JUMP("Select music playlists", "", "", runMusicSelection);
    366365    REG_JUMP("Rip CD",                 "", "", runRipCD);
    367366    REG_JUMP("Scan music",             "", "", runScan);
     367    REG_JUMP("Show Miniplayer",        "", "", showMiniPlayer);
    368368
    369369    REG_KEY("Music", "DELETE",     "Delete track from playlist", "D");
    370370    REG_KEY("Music", "NEXTTRACK",  "Move to the next track",     ">,.,Z,End");
     
    423423
    424424    Decoder::SetLocationFormatUseTags();
    425425
     426    gPlayer = new MusicPlayer(NULL, chooseCD());
     427
    426428    return 0;
    427429}
    428430
     
    585587
    586588    postMusic(&mdata);
    587589}
     590
     591void showMiniPlayer(void)
     592{
     593    // only show the miniplayer if there isn't already a client attached
     594    if (!gPlayer->hasClient())
     595        gPlayer->showMiniPlayer();
     596}
  • mythmusic/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
     48    QString playmode = gContext->GetSetting("PlayMode", "none");
     49    if (playmode.lower() == "random")
     50        setShuffleMode(SHUFFLE_RANDOM);
     51    else if (playmode.lower() == "intelligent")
     52        setShuffleMode(SHUFFLE_INTELLIGENT);
     53    else if (playmode.lower() == "album")
     54        setShuffleMode(SHUFFLE_ALBUM);
     55    else if (playmode.lower() == "artist")
     56        setShuffleMode(SHUFFLE_ARTIST);
     57    else
     58        setShuffleMode(SHUFFLE_OFF);
     59
     60    QString repeatmode = gContext->GetSetting("RepeatMode", "all");
     61    if (repeatmode.lower() == "track")
     62        setRepeatMode(REPEAT_TRACK);
     63    else if (repeatmode.lower() == "all")
     64        setRepeatMode(REPEAT_ALL);
     65    else
     66        setRepeatMode(REPEAT_OFF);
     67}
     68
     69MusicPlayer::~MusicPlayer()
     70{
     71    if (m_playlistTree)
     72        delete m_playlistTree;
     73
     74    stop(true);
     75
     76    if (m_currentMetadata)
     77        delete m_currentMetadata;
     78    m_currentMetadata = NULL;
     79}
     80
     81void MusicPlayer::setListener(QObject *listener)
     82{
     83    if (m_listener && m_output)
     84        m_output->removeListener(m_listener);
     85
     86    if (m_listener && m_decoder)
     87        m_decoder->removeListener(m_listener);
     88
     89    m_listener = listener;
     90
     91    if (m_listener && m_output)
     92        m_output->addListener(m_listener);
     93
     94    if (m_listener && m_decoder)
     95        m_decoder->addListener(m_listener);
     96
     97    (listener == NULL) ? m_isAutoplay = true :  m_isAutoplay = false;
     98}
     99
     100void MusicPlayer::setVisual(MainVisual *visual)
     101{
     102    if (m_visual && m_output)
     103    {
     104        m_output->removeListener(m_visual);
     105        m_output->removeVisual(m_visual);
     106    }
     107
     108    m_visual = visual;
     109
     110    if (m_visual && m_output)
     111    {
     112        m_output->addListener(m_visual);
     113        m_output->addVisual(m_visual);
     114    }
     115}
     116
     117void MusicPlayer::playFile(const Metadata &meta)
     118{
     119    playFile(meta.Filename());
     120}
     121
     122void MusicPlayer::playFile(const QString &filename)
     123{
     124    m_currentFile = filename;
     125    play();
     126}
     127
     128void MusicPlayer::stop(bool stopAll)
     129{
     130    stopDecoder();
     131
     132    if (m_output)
     133    {
     134        if (m_output->GetPause())
     135        {
     136            pause();
     137        }
     138        m_output->Reset();
     139    }
     140
     141    if (m_input)
     142        delete m_input;
     143    m_input = NULL;
     144
     145    m_isPlaying = false;
     146
     147    if (stopAll && m_decoder)
     148    {
     149        m_decoder->removeListener(this);
     150        if (m_listener)
     151            m_decoder->removeListener(m_listener);
     152
     153        // we can't delete m_decoder because we're using the shared Decoder
     154        //delete m_decoder;
     155        m_decoder = NULL;
     156        m_listener = NULL;
     157    }
     158
     159    if (stopAll && m_output)
     160    {
     161        m_output->removeListener(this);
     162        if (m_listener)
     163            m_output->removeListener(m_listener);
     164
     165        if (m_visual)
     166        {
     167            m_output->removeListener(m_visual);
     168            m_output->removeVisual(m_visual);
     169        }
     170        delete m_output;
     171        m_output = NULL;
     172        m_visual = NULL;
     173    }
     174}
     175
     176void MusicPlayer::pause(void)
     177{
     178    if (m_output)
     179    {
     180        m_isPlaying = !m_isPlaying;
     181        m_output->Pause(!m_isPlaying);
     182    }
     183    // wake up threads
     184    if (m_decoder)
     185    {
     186        m_decoder->lock();
     187        m_decoder->cond()->wakeAll();
     188        m_decoder->unlock();
     189    }
     190}
     191
     192void MusicPlayer::play(void)
     193{
     194    stopDecoder();
     195
     196    if (!m_output)
     197        openOutputDevice();
     198
     199    if (m_input)
     200        delete m_input;
     201
     202    m_input = new QFile(m_currentFile);
     203
     204    if (m_decoder && !m_decoder->factory()->supports(m_currentFile))
     205    {
     206        m_decoder->removeListener(this);
     207
     208        if (m_listener)
     209            m_decoder->removeListener(m_listener);
     210        // we can't delete m_decoder because we're using the shared Decoders
     211        //delete m_decoder;
     212        m_decoder = NULL;
     213    }
     214
     215    if (!m_decoder)
     216    {
     217        m_decoder = Decoder::create(m_currentFile, m_input, m_output);
     218        if (!m_decoder)
     219        {
     220            VERBOSE(VB_IMPORTANT, "MusicPlayer: Failed to create decoder for playback");
     221            return;
     222        }
     223
     224        if (m_currentFile.contains("cda") == 1)
     225            dynamic_cast<CdDecoder*>(m_decoder)->setDevice(m_CDdevice);
     226
     227        m_decoder->setBlockSize(2 * 1024);
     228
     229        m_decoder->addListener(this);
     230
     231        if (m_listener)
     232            m_decoder->addListener(m_listener);
     233    }
     234    else
     235    {
     236        m_decoder->setInput(m_input);
     237        m_decoder->setFilename(m_currentFile);
     238        m_decoder->setOutput(m_output);
     239    }
     240
     241    if (m_decoder->initialize())
     242    {
     243        if (m_output)
     244            m_output->Reset();
     245
     246        m_decoder->start();
     247
     248        m_isPlaying = true;
     249
     250        if (m_currentNode)
     251        {
     252            if (m_currentNode->getInt() > 0)
     253            {
     254                m_currentMetadata = Metadata::getMetadataFromID(m_currentNode->getInt());
     255                if (m_currentMetadata)
     256                {
     257                    m_currentMetadata->incPlayCount();
     258                    m_currentMetadata->setLastPlay();
     259                }
     260            }
     261            else
     262            {
     263                // CD track
     264                CdDecoder *cddecoder = dynamic_cast<CdDecoder*>(m_decoder);
     265                if (m_decoder)
     266                    m_currentMetadata = cddecoder->getMetadata(-m_currentNode->getInt());
     267            }
     268        }
     269    }
     270}
     271
     272void MusicPlayer::stopDecoder(void)
     273{
     274    if (m_decoder && m_decoder->running())
     275    {
     276        m_decoder->lock();
     277        m_decoder->stop();
     278        m_decoder->unlock();
     279    }
     280
     281    if (m_decoder)
     282    {
     283        m_decoder->lock();
     284        m_decoder->cond()->wakeAll();
     285        m_decoder->unlock();
     286    }
     287
     288    if (m_decoder)
     289        m_decoder->wait();
     290
     291    if (m_currentMetadata)
     292    {
     293        if (m_currentMetadata->hasChanged())
     294            m_currentMetadata->persist();
     295        delete m_currentMetadata;
     296    }
     297    m_currentMetadata = NULL;
     298}
     299
     300void MusicPlayer::openOutputDevice(void)
     301{
     302    QString adevice;
     303
     304    if (gContext->GetSetting("MusicAudioDevice") == "default")
     305        adevice = gContext->GetSetting("AudioOutputDevice");
     306    else
     307        adevice = gContext->GetSetting("MusicAudioDevice");
     308
     309    // TODO: Error checking that device is opened correctly!
     310    m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
     311                                    AUDIOOUTPUT_MUSIC, true, false);
     312    m_output->setBufferSize(256 * 1024);
     313    m_output->SetBlocking(false);
     314
     315    m_output->addListener(this);
     316
     317    if (m_listener)
     318        m_output->addListener(m_listener);
     319
     320    if (m_visual)
     321    {
     322        m_output->addListener((QObject*) m_visual);
     323        m_output->addVisual(m_visual);
     324    }
     325}
     326
     327void MusicPlayer::next(void)
     328{
     329    if (!m_currentNode)
     330        return;
     331
     332    GenericTree *node = m_currentNode->nextSibling(1, ((int) m_shuffleMode) + 1);
     333    if (node)
     334    {
     335        m_currentNode = node;
     336    }
     337    else
     338    {
     339        if (m_repeatMode == REPEAT_ALL)
     340        {
     341            // start playing again from first track
     342            GenericTree *parent = m_currentNode->getParent();
     343            if (parent)
     344            {
     345                node = parent->getChildAt(0, ((int) m_shuffleMode) + 1);
     346                if (node)
     347                    m_currentNode = node;
     348                else
     349                    return; // stop()
     350            }
     351        }
     352        else
     353            return; // stop()
     354    }
     355
     356    QString filename = getFilenameFromID(node->getInt());
     357    if (!filename.isEmpty())
     358        playFile(filename);
     359    else
     360        stop();
     361}
     362
     363void MusicPlayer::previous(void)
     364{
     365    if (!m_currentNode)
     366        return;
     367
     368    GenericTree *node = m_currentNode->prevSibling(1, ((int) m_shuffleMode) + 1);
     369    if (node)
     370    {
     371        m_currentNode = node;
     372        QString filename = getFilenameFromID(node->getInt());
     373        if (!filename.isEmpty())
     374            playFile(filename);
     375        else
     376            return;//stop();
     377    }
     378    else
     379    {
     380        // FIXME take repeat mode into account
     381        return; //stop();
     382    }
     383}
     384
     385void MusicPlayer::nextAuto(void)
     386{
     387    if (!m_isAutoplay)
     388        return;
     389
     390    if (!m_currentNode)
     391        return;
     392
     393    if (m_repeatMode == REPEAT_TRACK)
     394    {
     395        play();
     396        return;
     397    }
     398    else
     399        next();
     400
     401    MiniPlayer *popup = new MiniPlayer(gContext->GetMainWindow(), this);
     402    gContext->GetMainWindow()->detach(popup);
     403    popup->showPlayer(10);
     404    popup->deleteLater();
     405    popup = NULL;
     406}
     407
     408void MusicPlayer::customEvent(QCustomEvent *event)
     409{
     410    if (m_isAutoplay)
     411    {
     412        switch ((int)event->type())
     413        {
     414            case OutputEvent::Error:
     415            {
     416                OutputEvent *aoe = (OutputEvent *) event;
     417
     418                VERBOSE(VB_IMPORTANT, QString("Output Error - %1")
     419                        .arg(*aoe->errorMessage()));
     420                MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     421                        "Output Error:",
     422                        QString("MythMusic has encountered the following error:\n%1")
     423                                .arg(*aoe->errorMessage()));
     424                stop(true);
     425
     426                break;
     427            }
     428
     429            case DecoderEvent::Finished:
     430            {
     431                nextAuto();
     432                break;
     433            }
     434
     435            case DecoderEvent::Error:
     436            {
     437                stop(true);
     438
     439                QApplication::sendPostedEvents();
     440
     441                DecoderEvent *dxe = (DecoderEvent *) event;
     442
     443                VERBOSE(VB_IMPORTANT, QString("Decoder Error - %1")
     444                        .arg(*dxe->errorMessage()));
     445                MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     446                                        "Decoder Error",
     447                                        QString("MythMusic has encountered the following error:\n%1")
     448                                        .arg(*dxe->errorMessage()));
     449                break;
     450            }
     451        }
     452    }
     453
     454    QObject::customEvent(event);
     455}
     456
     457QString MusicPlayer::getFilenameFromID(int id)
     458{
     459    QString filename = "";
     460
     461    if (id > 0)
     462    {
     463        QString aquery = "SELECT CONCAT_WS('/', "
     464                        "music_directories.path, music_songs.filename) AS filename "
     465                        "FROM music_songs "
     466                        "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
     467                        "WHERE music_songs.song_id = :ID";
     468
     469        MSqlQuery query(MSqlQuery::InitCon());
     470        query.prepare(aquery);
     471        query.bindValue(":ID", id);
     472        if (!query.exec() || query.numRowsAffected() < 1)
     473            MythContext::DBError("get filename", query);
     474
     475        if (query.isActive() && query.size() > 0)
     476        {
     477            query.first();
     478            filename = QString::fromUtf8(query.value(0).toString());
     479            if (!filename.contains("://"))
     480                filename = Metadata::GetStartdir() + filename;
     481        }
     482    }
     483    else
     484    {
     485        // cd track
     486        CdDecoder *cddecoder = dynamic_cast<CdDecoder*>(m_decoder);
     487        if (m_decoder)
     488        {
     489            Metadata *meta = cddecoder->getMetadata(-id);
     490            if (meta)
     491                filename = meta->Filename();
     492        }
     493    }
     494    return filename;
     495}
     496
     497QString MusicPlayer::getRouteToCurrent(void)
     498{
     499    QStringList route;
     500
     501    if (m_currentNode)
     502    {
     503        GenericTree *climber = m_currentNode;
     504
     505        route.push_front(QString::number(climber->getInt()));
     506        while((climber = climber->getParent()))
     507        {
     508            route.push_front(QString::number(climber->getInt()));
     509        }
     510    }
     511    return route.join(",");
     512}
     513
     514void MusicPlayer::showMiniPlayer(void)
     515{
     516    MiniPlayer *popup = new MiniPlayer(gContext->GetMainWindow(), this);
     517    gContext->GetMainWindow()->detach(popup);
     518    popup->exec();
     519    popup->deleteLater();
     520    popup = NULL;
     521}
     522
     523Metadata *MusicPlayer::getCurrentMetadata(void)
     524{
     525    if (!m_currentNode)
     526        return NULL;
     527
     528    if (m_currentMetadata)
     529        return m_currentMetadata;
     530
     531    m_currentMetadata = Metadata::getMetadataFromID(m_currentNode->getInt());
     532
     533    return m_currentMetadata;
     534}
     535
     536MusicPlayer::RepeatMode MusicPlayer::toggleRepeatMode(void)
     537{
     538    switch (m_repeatMode)
     539    {
     540        case REPEAT_OFF:
     541            m_repeatMode = REPEAT_TRACK;
     542            break;
     543        case REPEAT_TRACK:
     544            m_repeatMode = REPEAT_ALL;
     545            break;
     546        case REPEAT_ALL:
     547            m_repeatMode = REPEAT_OFF;
     548           break;
     549        default:
     550            m_repeatMode = REPEAT_OFF;
     551            break;
     552    }
     553
     554    return m_repeatMode;
     555}
     556
     557MusicPlayer::ShuffleMode MusicPlayer::toggleShuffleMode(void)
     558{
     559    switch (m_shuffleMode)
     560    {
     561        case SHUFFLE_OFF:
     562            m_shuffleMode = SHUFFLE_RANDOM;
     563            break;
     564        case SHUFFLE_RANDOM:
     565            m_shuffleMode = SHUFFLE_INTELLIGENT;
     566            break;
     567        case SHUFFLE_INTELLIGENT:
     568            m_shuffleMode = SHUFFLE_ALBUM;
     569           break;
     570        case SHUFFLE_ALBUM:
     571            m_shuffleMode = SHUFFLE_ARTIST;
     572           break;
     573        case SHUFFLE_ARTIST:
     574            m_shuffleMode = SHUFFLE_OFF;
     575           break;
     576        default:
     577            m_shuffleMode = SHUFFLE_OFF;
     578            break;
     579    }
     580
     581    return m_shuffleMode;
     582}
  • mythmusic/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;
     
    3337
    3438    ~PlaybackBoxMusic(void);
    3539
    36     void closeEvent(QCloseEvent *);
    3740    void customEvent(QCustomEvent *);
    38     void showEvent(QShowEvent *);
    3941    void keyPressEvent(QKeyEvent *e);
    4042    void constructPlaylistTree();
    4143
     
    4446  public slots:
    4547
    4648    void play();
    47     void pause();
    4849    void stop();
     50    void pause();
    4951    void stopDecoder();
    5052    void previous();
    5153    void next();
     
    5355    void seekback();
    5456    void seek(int);
    5557    void stopAll();
    56     void setShuffleMode(unsigned int mode);
     58    void setShuffleMode(MusicPlayer::ShuffleMode mode);
    5759    void toggleShuffle();
    5860    void increaseRating();
    5961    void decreaseRating();
    60     void setRepeatMode(unsigned int mode);
     62    void setRepeatMode(MusicPlayer::RepeatMode mode);
    6163    void toggleRepeat();
    6264    void editPlaylist();
    6365    void nextAuto();
     
    109111    void updatePlaylistFromCD(void);
    110112    void setTrackOnLCD(Metadata *mdata);
    111113    void updateTrackInfo(Metadata *mdata);
    112     void openOutputDevice(void);
    113114    void postUpdate();
    114115    void playFirstTrack();
    115116    void bannerEnable(QString text, int millis);
    116117    void bannerEnable(Metadata *mdata, bool fullScreen = false);
    117118    void bannerToggle(Metadata *mdata);
    118119    void savePosition(uint position);
    119     void restorePosition(void);
     120    void restorePosition(const QString &position);
    120121    void pushButton(UIPushButtonType *button);
    121122    QString getTimeString(int exTime, int maxTime);
    122123
    123     QIODevice *input;
    124     AudioOutput *output;
    125     Decoder *decoder;
    126 
    127124    QString playfile;
    128125    QString statusString;
    129126    QString curSmartPlaylistCategory;
    130127    QString curSmartPlaylistName;
    131128
    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     };
    146129    enum ResumeMode
    147130    { RESUME_OFF,
    148131      RESUME_TRACK,
     
    158141
    159142    Metadata *curMeta;
    160143
    161 
    162     unsigned int shufflemode;
    163     unsigned int repeatmode;
    164144    unsigned int resumemode;
    165145
    166     bool isplaying;
    167 
    168146    bool menufilters;
    169147
    170148    ReadCDThread *cd_reader_thread;
     
    195173    QTimer  *waiting_for_playlists_timer;
    196174    QTimer  *volume_display_timer;
    197175
    198     GenericTree *playlist_tree;
    199 
    200176    bool cycle_visualizer;
    201177    bool random_visualizer;
    202178    bool show_album_art;
  • mythmusic/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
     37  protected:
     38    virtual void keyPressEvent(QKeyEvent *e);
     39    virtual void customEvent(QCustomEvent *event);
     40
     41  private:
     42    void    wireupTheme(void);
     43    QString getTimeString(int exTime, int maxTime);
     44    void    updateTrackInfo(Metadata *mdata);
     45    void    seekforward(void);
     46    void    seekback(void);
     47    void    seek(int pos);
     48    void    increaseRating(void);
     49    void    decreaseRating(void);
     50
     51    int           m_currTime, m_maxTime;
     52
     53    MusicPlayer  *m_parentPlayer;
     54    int           m_popupWidth;
     55    int           m_popupHeight;
     56
     57    QTimer       *m_displayTimer;
     58
     59    UITextType   *m_titleText;
     60    UITextType   *m_artistText;
     61    UITextType   *m_albumText;
     62    UITextType   *m_timeText;
     63    UITextType   *m_infoText;
     64    UIImageType  *m_coverImage;
     65
     66    UITextType   *m_shufflestateText;
     67    UITextType   *m_repeatstateText;
     68
     69    UIRepeatedImageType *m_ratingsImage;
     70};
     71
     72#endif