⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist.cpp

📁 WINCE XAUDIO可播放各种音乐格式内附SOURCE CODE可以再不同CPU 平台编译测试
💻 CPP
字号:
/*****************************************************************
|
|      PlayList Management
|
|
|      (c) 1996-1998 MpegTV, LLC
|      Author: Gilles Boccon-Gibod (gilles@mpegtv.com)
|
 ****************************************************************/

/*----------------------------------------------------------------------
|       includes
+---------------------------------------------------------------------*/
#include "playlist.h"

/*----------------------------------------------------------------------
|       constants
+---------------------------------------------------------------------*/
#ifndef NULL
#define NULL 0
#endif

/*----------------------------------------------------------------------
|       PlayList::PlayList
+---------------------------------------------------------------------*/
PlayList::PlayList() : 
    m_CallbackClient(NULL),
    m_CallbackFunction(NULL),
    m_Root(NULL), 
    m_Current(NULL),
    m_Mode(0),
    m_DefaultAction(PLAYLIST_ACTION_NONE)
{
    // TODO
}

/*----------------------------------------------------------------------
|       PlayList::~PlayList
+---------------------------------------------------------------------*/
PlayList::~PlayList()
{
    if (m_Root) delete m_Root;
}

/*----------------------------------------------------------------------
|       PlayList::RegisterCallback
+---------------------------------------------------------------------*/
void 
PlayList::RegisterCallback(PlayListCallback callback, void *client)
{
    m_CallbackFunction = callback;
    m_CallbackClient   = client;
}

/*----------------------------------------------------------------------
|       PlayList::Clear
+---------------------------------------------------------------------*/
void
PlayList::Clear()
{
    if (m_Root) delete m_Root;
}

/*----------------------------------------------------------------------
|       PlayList::AddTrack
+---------------------------------------------------------------------*/
int
PlayList::AddTrack(const char *name)
{
    // we must have a root
    if (m_Root == NULL) {
        m_Root = new PlayListItem(this, "root");
    }

    return AddTrack(m_Root, name);
}

/*----------------------------------------------------------------------
|       PlayList::AddTrack
+---------------------------------------------------------------------*/
int
PlayList::AddTrack(PlayListItem *parent, const char *name)
{
    PlayListItem *item;

    // create a new item
    item = new PlayListItem(parent, name);

    // add the item to the parent's children
    parent->AddChild(item);

    // notify the client
    if (m_CallbackFunction) {
        m_CallbackFunction(m_CallbackClient,
                           this,
                           PLAYLIST_EVENT_ITEM_CREATED,
                           (void *)item);
    }

    // if we had no current track, make this one current
    if (m_Current == NULL) {
        SetCurrent(item);
    }

    return PLAYLIST_SUCCESS;
}

/*----------------------------------------------------------------------
|       PlayList::SetMode
+---------------------------------------------------------------------*/
void
PlayList::SetMode(unsigned int mask, unsigned int mode)
{
    m_Mode = (m_Mode ^ mask) | mode;
    if (m_Mode & PLAYLIST_MODE_PLAYING) {
        m_DefaultAction = PLAYLIST_ACTION_PLAY;
    } else {
        m_DefaultAction = PLAYLIST_ACTION_NONE;
    }
}

/*----------------------------------------------------------------------
|       PlayList::SetCurrent
+---------------------------------------------------------------------*/
int
PlayList::SetCurrent(PlayListItem *item, PlayListAction action)
{
    PlayListCurrentChangedEvent event;

    // notify if the current item has changed
    if (m_CallbackFunction) {
        // setup event info
        event.current  = item;
        event.previous = m_Current;
        event.action   = action;

        // change current
        m_Current = item;

        // notify
        m_CallbackFunction(m_CallbackClient,
                           this,
                           PLAYLIST_EVENT_CURRENT_CHANGED,
                           (void *)&event);
    }

    // mark the new current item played
    if (action == PLAYLIST_ACTION_PLAY) {
        item->m_Status |= PLAYLIST_STATUS_PLAYED;
    }

    return PLAYLIST_SUCCESS;
}

/*----------------------------------------------------------------------
|       PlayList::Play
+---------------------------------------------------------------------*/
int
PlayList::Play()
{
    if (m_Current) return m_Current->Play();
    if (m_Root) {
        return m_Root->Play();
    }

    return PLAYLIST_FAILURE;
}

/*----------------------------------------------------------------------
|       PlayList::Stop
+---------------------------------------------------------------------*/
int
PlayList::Stop()
{
    if (m_CallbackFunction) {
        m_CallbackFunction(m_CallbackClient,
                           this,
                           PLAYLIST_EVENT_STOP_PLAYING,
                           NULL);
    }

    return PLAYLIST_SUCCESS;
}

/*----------------------------------------------------------------------
|       PlayList::Next
+---------------------------------------------------------------------*/
int
PlayList::Next()
{
    if (m_Current) {
        return m_Current->Next();
    } else {
        if (m_Root) {
            return m_Root->DoAction(m_DefaultAction);
        }
    }

    return PLAYLIST_FAILURE;
}

/*----------------------------------------------------------------------
|       PlayList::Prev
+---------------------------------------------------------------------*/
int
PlayList::Prev()
{
    if (m_Current) {
        return m_Current->Prev();
    }

    return PLAYLIST_FAILURE;
}

/*----------------------------------------------------------------------
|       PlayListItem::PlayListItem
+---------------------------------------------------------------------*/
PlayListItem::PlayListItem(PlayList *owner, const char *name)
{
    Init();
    m_PlayList = owner;
    SetName(name);
}

/*----------------------------------------------------------------------
|       PlayListItem::PlayListItem
+---------------------------------------------------------------------*/
PlayListItem::PlayListItem(PlayListItem *parent, const char *name)
{
    Init();
    m_PlayList = parent->m_PlayList;
    SetName(name);
}

/*----------------------------------------------------------------------
|       PlayListItem::~PlayListItem
+---------------------------------------------------------------------*/
PlayListItem::~PlayListItem()
{
    // first, delete the children
    PlayListItem *item = m_FirstChild;
    while (item) {
        PlayListItem *next = item->m_RightSibling;
        delete item;
        item = next;
    }

    if (m_LeftSibling) {
        // we are not first child
        m_LeftSibling->m_RightSibling = m_RightSibling;
    } else {
        // we are fist child
        if (m_Parent) {
            m_Parent->m_FirstChild = m_RightSibling;
        }
    }
    if (m_RightSibling) {
        m_RightSibling->m_LeftSibling = m_LeftSibling;
    }

    // if we were the curren item, change current
    if (m_PlayList->m_Current == this) {
        m_PlayList->m_Current = m_LeftSibling;
    }

    // if we are the root, set the root to NULL
    if (m_PlayList->m_Root == this) {
        m_PlayList->m_Root = NULL;
    }

    // notify the client
    if (m_PlayList &&
        m_PlayList->m_CallbackFunction) {
        m_PlayList->m_CallbackFunction(m_PlayList->m_CallbackClient,
                                       m_PlayList,
                                       PLAYLIST_EVENT_ITEM_DELETED,
                                       (void *)this);
    }

    // free the strings
    if (m_FullName) delete[] m_FullName;
    if (m_ShortName) delete[] m_FullName;
    if (m_GroupName) delete[] m_GroupName;
}

/*----------------------------------------------------------------------
|       PlayListItem::Init
+---------------------------------------------------------------------*/
void
PlayListItem::Init()
{
    m_PlayList     = NULL;
    m_Parent       = NULL;
    m_FirstChild   = NULL;
    m_RightSibling = NULL;
    m_LeftSibling  = NULL;
    m_Status       = 0;
    m_ClientData   = 0;
}

/*----------------------------------------------------------------------
|       PlayListItem::SetName
+---------------------------------------------------------------------*/
void
PlayListItem::SetName(const char *name)
{
    const char *ptr = name;

    // go to the end of the string
    int full_name_size = 0;
    while (*ptr) {
        ptr++;
        full_name_size++;
    }

    // copy the full name 
    m_FullName = new char[full_name_size+1];
    for (int i=0; i<=full_name_size; i++) {
        m_FullName[i] = name[i];
    }

    // rewind until we find a / or \ or reach the start
    int short_name_size = 0;
    while (ptr     != name &&
           ptr[-1] != '/' &&
           ptr[-1] != '\\') {
        ptr--;
        short_name_size++;
    }

    // copy the short name
    m_ShortName = new char[short_name_size+1];
    for (i=0; i<=short_name_size; i++) {
        m_ShortName[i] = ptr[i];
    }
}

/*----------------------------------------------------------------------
|       PlayListItem::AddChild
+---------------------------------------------------------------------*/
void
PlayListItem::AddChild(PlayListItem *item)
{
    // set the parent
    item->m_Parent = this;

    // add to the list of children
    if (m_FirstChild) {
        PlayListItem *child = m_FirstChild;
        while (child->m_RightSibling) child = child->m_RightSibling;
        child->m_RightSibling = item;
        item->m_LeftSibling = child;
    } else {
        m_FirstChild = item;
    }
}

/*----------------------------------------------------------------------
|       PlayListItem::DoAction
+---------------------------------------------------------------------*/
int
PlayListItem::DoAction(PlayListAction action)
{
    PlayListItem *target;
    if (m_FirstChild) {
        target = m_FirstChild;
    } else {
        target = this;
    }
    m_PlayList->SetCurrent(target, action);
    
    return PLAYLIST_SUCCESS;
}

/*----------------------------------------------------------------------
|       PlayListItem::Play
+---------------------------------------------------------------------*/
int
PlayListItem::Play()
{
    return DoAction(PLAYLIST_ACTION_PLAY);
}

/*----------------------------------------------------------------------
|       PlayListItem::Next
+---------------------------------------------------------------------*/
int
PlayListItem::Next()
{
    if (m_RightSibling) {
        return m_RightSibling->DoAction(m_PlayList->m_DefaultAction);
    } else {
        if (m_PlayList->m_Mode & PLAYLIST_MODE_LOOP) {
            m_PlayList->m_Root->DoAction(m_PlayList->m_DefaultAction);
        } else {
            if (m_PlayList->m_Mode & PLAYLIST_MODE_PLAYING) {
                m_PlayList->Stop();
            }
            m_PlayList->m_Root->DoAction(PLAYLIST_ACTION_NONE);
        }
    }

    return PLAYLIST_FAILURE;
}

/*----------------------------------------------------------------------
|       PlayListItem::Prev
+---------------------------------------------------------------------*/
int
PlayListItem::Prev()
{
    if (m_LeftSibling) {
        return m_LeftSibling->DoAction(m_PlayList->m_DefaultAction);
    }

    return PLAYLIST_FAILURE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -