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

📄 apsinterface.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*________________________________________________________________________
        
        FreeAmp - The Free MP3 Player

        Portions Copyright (C) 2000 Relatable

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, Write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        
        $Id: apsinterface.cpp,v 1.45 2001/03/06 04:29:20 ijr Exp $
____________________________________________________________________________*/

///////////////////////////////////////////////////////////////////
// Copyright 1999 Relatable, LLC. All Rights Reserved
// Programed By: Sean Ward
// Description: Interface declaration file for Relatable APS system
// Date: 12/13/1999
// Modification History:
// 12/13/1999 : First Created
// Sometime: Stuff
// 07/25/2000 : Lots of stuff/cruft/hallucinations cleaned up
///////////////////////////////////////////////////////////////////
#ifdef WIN32
#pragma warning(disable:4786)
#endif

#include "aps.h"
#include "apsplaylist.h"
#include "apsmetadata.h"
#include "uuid.h"
#include <strstream>

#ifdef WIN32
#include "wincomsocket.h"
#else
#include "comsocket.h"
#endif

#include "config.h"
#include "mutex.h"
#include "semaphore.h"
#include "YPClient.h"
#include "apsutility.h"
#include "apsconvert.h"
#include <math.h>
#include <musicbrainz/mb_c.h>
#include "utility.h"

#ifndef WIN32
#define ios_base ios
#endif

const int nAPSYPPort  = 4444;
const int nAPSSigPort = 4445;

APSInterface::APSInterface(FAContext *context, const char* pIP, 
                           const char *pSigIP)
{
    //srand((unsigned)time(NULL)); // comment out if already inited elsewhere
    m_strIP = pIP;
    m_sigIP = pSigIP;
    m_pMutex = new Mutex();
    m_pSema = new Semaphore(MAX_METADATAQUERIES);
    m_pProfileMap = new map<string, string>;
    m_pActiveProfiles = new vector<string>;

    m_bRelatableOn = true;

    m_pLogFile = NULL;
    m_context = context;
    m_profilePath = string(FreeampDir(m_context->prefs));
    string savedProfiles = m_profilePath + string(DIR_MARKER_STR) +
                           string("profiles.txt");

    LoadProfileMap(savedProfiles.c_str()); // could be made into a configurable option

    m_pYpClient = new YPClient;
    m_pYpClient->SetAddress(m_strIP.c_str(), nAPSYPPort);
    m_nMetaFailures = 0;

    if (!m_strCurrentProfile.empty()) {
        ChangeProfile(m_strCurrentProfile.c_str());
        //SyncLog();
    }
}

APSInterface::~APSInterface()
{
    string savedProfiles = m_profilePath + string(DIR_MARKER_STR) +
                           string("profiles.txt");
    WriteProfileMap(savedProfiles.c_str());

    if (m_pYpClient != NULL) 
    {
        delete m_pYpClient;
        m_pYpClient = NULL;
    }
    if (m_pMutex != NULL) 
    {
        delete m_pMutex;
        m_pMutex = NULL;
    }
    if (m_pSema != NULL) 
    {
        delete m_pSema;
        m_pSema = NULL;
    }
    if (m_pLogFile != NULL)
    {
        m_pLogFile->close();
        delete m_pLogFile;
        m_pLogFile = NULL;
    }
    if (m_pProfileMap != NULL)
    {
        delete m_pProfileMap;
        m_pProfileMap = NULL;
    }
    if (m_pActiveProfiles != NULL)
    {
        delete m_pActiveProfiles;
        m_pActiveProfiles = NULL;
    }
}

void APSInterface::SetProxy(string strAddr, int nPort)
{
    m_strProxyAddr = strAddr;
    m_nProxyPort = nPort;
    if (m_pYpClient)
        m_pYpClient->SetProxy(m_strProxyAddr, m_nProxyPort);
}

int APSInterface::APSFillMetaData(APSMetaData* pmetaData)
{
    if (pmetaData == NULL) 
        return APS_PARAMERROR;

    m_pSema->Wait();

    musicbrainz_t o;
    int    ret;
    char   *args[20];
    char    temp[255], guid[40], url[MAX_PATH];
    char    hostname[MAX_PATH], file[MAX_PATH];
    int     i, port;
    uint32  len = MAX_PATH;
    BitprintInfo  info;

    memset(args, 0, sizeof(args));

    // Parse the musicbrainz server from the preference
    m_context->prefs->GetPrefString(kMBServerPref, url, &len);
    i = sscanf(url, " http://%[^:/]:%d", hostname, &port);
    if (i == 0)
        i = sscanf(url, " %[^:/]:%d", hostname, &port);
    if (i < 2)
        port = MUSICBRAINZ_PORT;
    if (i < 1)
        strcpy(hostname, MUSICBRAINZ_SERVER);

    o = mb_New();

    // Calculate the bitzi bitprint for this file.
    len = MAX_PATH;
    URLToFilePath((char *)pmetaData->Filename().c_str(), file, &len);
    mb_CalculateBitprint(o, file, &info);

    mb_UseUTF8(o, 0);
    mb_SetServer(o, hostname, port);
    if (m_strProxyAddr.size() > 7)
        mb_SetProxy(o, (char *)m_strProxyAddr.c_str(), m_nProxyPort);

    uuid_ascii((unsigned char*)pmetaData->GUID().c_str(), guid);

    string guidMapping = m_profilePath + string(DIR_MARKER_STR) +
                         string("guid_mapping.txt");

    FILE *guidLogfile = fopen(guidMapping.c_str(), "a+");
    fprintf(guidLogfile, "%s\t%s\n", pmetaData->Filename().c_str(),
                                     guid);
    fclose(guidLogfile);

    args[0] = strdup(pmetaData->Title().c_str());
    args[1] = strdup(pmetaData->Artist().c_str());
    args[2] = strdup(pmetaData->Album().c_str());
    sprintf(temp, "%d", pmetaData->Track());
    args[3] = strdup(temp);
    args[4] = strdup(guid);
    args[5] = strdup(pmetaData->Filename().c_str());
    sprintf(temp, "%d", pmetaData->Year());
    args[6] = strdup(temp);
    args[7] = strdup(pmetaData->Genre().c_str());
    args[8] = strdup(pmetaData->Comment().c_str());

    // These are the bitzi bitpint metadata items
    args[9] = strdup(info.bitprint);
    args[10] = strdup(info.first20);
    sprintf(temp, "%d", info.length);
    args[11] = strdup(temp);

    if (info.audioSha1)
    {
        args[12] = strdup(info.audioSha1);
        sprintf(temp, "%d", info.duration);
        args[13] = strdup(temp);
        sprintf(temp, "%d", info.samplerate);
        args[14] = strdup(temp);
        sprintf(temp, "%d", info.bitrate);
        args[15] = strdup(temp);
        sprintf(temp, "%d", info.stereo);
        args[16] = strdup(temp);
        sprintf(temp, "%d", info.vbr);
        args[17] = strdup(temp);
        args[18] = NULL;
    }
    else
    {
        args[12] = NULL;
    }

    ret = mb_QueryWithArgs(o, MB_ExchangeMetadata, args);
    for(i = 0; i < 11; i++)
       if (args[i])
           free(args[i]);

    if (!ret)
    {
        m_pSema->Signal();
        return APS_NETWORKERROR;
    }

    // This query should always return one item
    if (mb_GetNumItems(o) == 0)
    {
        m_pSema->Signal();
        return APS_GENERALERROR;
    }

    // Now start the data extraction process.
    // Select the album context of the exchanged data
    mb_Select(o, MB_SelectExchangedAlbum);
    if (mb_GetResultData(o, MB_GetAlbumName, temp, 255))
        pmetaData->SetAlbum(temp);

    // Select the main context of the exchanged data
    mb_Select(o, MB_SelectExchangedData);

    if (mb_GetResultData(o, MB_GetArtistName, temp, 255))
        pmetaData->SetArtist(temp);
    if (mb_GetResultData(o, MB_GetTrackName, temp, 255))
        pmetaData->SetTitle(temp);
    if (mb_GetResultData(o, MB_GetGenre, temp, 255))
        pmetaData->SetGenre(temp);
    if (mb_GetResultData(o, MB_GetDescription, temp, 255))
        pmetaData->SetComment(temp);
    pmetaData->SetYear(mb_GetResultInt(o, MB_GetYear));
    pmetaData->SetTrack(mb_GetResultInt(o, MB_GetTrackNum));
    pmetaData->SetLength(mb_GetResultInt(o, MB_GetDuration));

    mb_Delete(o);

    m_pSema->Signal();

    return APS_NOERROR;
}

int APSInterface::APSGetSoundsLike(APSPlaylist *pSeedList,
                                   APSPlaylist *pReturnList,
                                   int nMaxItems)
{
    if ((pSeedList == NULL) || (pReturnList == NULL)) 
        return APS_PARAMERROR;

    m_pMutex->Acquire();

    string strUID = "";
    if (!m_strCurrentProfile.empty())
        strUID = (*m_pProfileMap)[m_strCurrentProfile];
    if (strUID.empty())
        strUID = "NOT_OPTED_IN1111"; // 16 char aggregate query id

    int nRes = m_pYpClient->SoundsLike(*pReturnList, *pSeedList, 
                                       m_strCollectionID);

    m_pMutex->Release();

    return nRes;
}

int APSInterface::APSGetPlaylist(APSPlaylist* pPlayList, 
                                 APSPlaylist* pResultList, int nMaxItems, 
                                 bool bLocalOnly)
{
    if ((pPlayList == NULL) || (pResultList == NULL)) 
        return APS_PARAMERROR;

    m_pMutex->Acquire();

    string strUID = "";
    if (!m_strCurrentProfile.empty())
        strUID = (*m_pProfileMap)[m_strCurrentProfile];
    if (strUID.empty())
        strUID = "NOT_OPTED_IN1111"; // 16 char aggregate query id

    int nRes = m_pYpClient->GeneratePlayList(*pResultList, *pPlayList, 
                                             nMaxItems, bLocalOnly, strUID,
                                             m_strCollectionID);
    m_pMutex->Release();

    return nRes;
}

int APSInterface::APSSubmitPlaylist(APSPlaylist* pPlayList)
{
    if (pPlayList == NULL)  
        return APS_PARAMERROR;

    m_pMutex->Acquire();
    string strUID = "";

    if (!m_strCurrentProfile.empty())
        strUID = (*m_pProfileMap)[m_strCurrentProfile];

    if (strUID.empty())
        strUID = "NOT_OPTED_IN1111";        // 16 char aggregate query id
    int nRes = m_pYpClient->SubmitPlaylist(*pPlayList, strUID);
    m_pMutex->Release();

    return nRes;
}

void APSInterface::WriteToLog(const string& strGUID, int nEventType)
{
    if (m_strCurrentProfile.empty())
        return;  // if no active profile, don't log anything

    m_pMutex->Acquire();
    if (m_pLogFile == NULL)
    {
        // name the logfile after the profile alias
        string logfilename = m_profilePath + string(DIR_MARKER_STR) +
                             m_strCurrentProfile;

        m_pLogFile = new fstream(logfilename.c_str(), 
                                 ios_base::out | ios_base::app);
    }

    time_t currenttime;
    time(&currenttime);

    *m_pLogFile << currenttime << " " << strGUID << " " << nEventType << endl;

    m_pMutex->Release();
}

int APSInterface::ChangeProfile(const char *pczUserName)
{
    if (pczUserName == NULL)
        return APS_PARAMERROR;  

    if (m_pProfileMap->empty())
        return APS_PARAMERROR;

    map<string, string>::iterator i;
    i = m_pProfileMap->find(pczUserName);
    if (i != m_pProfileMap->end())
    {
        if (m_pLogFile != NULL)
        {
            if (m_pLogFile->is_open()) 
                m_pLogFile->close();
            delete m_pLogFile;
            m_pLogFile = NULL;
        }
		
        m_strCurrentProfile = pczUserName;

        CombineProfile(pczUserName);

        string logfilename = m_profilePath + string(DIR_MARKER_STR) + 
                             string(pczUserName);
        m_pLogFile = new fstream(logfilename.c_str(), 
                                 ios_base::out | ios_base::app);

        string savedProfiles = m_profilePath + string(DIR_MARKER_STR) +
                               string("profiles.txt");
        WriteProfileMap(savedProfiles.c_str());

        return APS_NOERROR;
    }
    else
        return APS_PARAMERROR;
}

int APSInterface::APSGetStreams(vector<pair<string, string> >* pResultList)
{
    if (pResultList == NULL) 
        return APS_PARAMERROR;

    m_pMutex->Acquire();
    
    string strUID = "";
       
    if (!m_strCurrentProfile.empty())
        strUID = (*m_pProfileMap)[m_strCurrentProfile];
       
    if (strUID.empty()) 
        strUID = "NOT_OPTED_IN1111";        // 16 char aggregate query id
       
    int nRes = m_pYpClient->GetStreams(*pResultList, strUID, m_strCollectionID);
       
    fstream fout("test.txt", ios_base::in | ios_base::out | ios_base::app);
    fout << "GetStream returned: " << nRes << " and filled in " <<
            pResultList->size() << " items:" << endl;
    vector<pair<string, string> >::iterator i;
    for (i = pResultList->begin(); i != pResultList->end(); i++)
    {
        fout << (*i).first << " : " << (*i).second << endl;
    }
    fout.close();

    m_pMutex->Release();

    return nRes;
}

int APSInterface::CreateProfile(const char *pczNewName)
{
    if (pczNewName == NULL) 
        return APS_PARAMERROR;

    m_pMutex->Acquire();

    if ((m_pProfileMap->empty()) || 
        (m_pProfileMap->end() == m_pProfileMap->find(pczNewName)))
    {
        string strGUID = "";
        int nRes = m_pYpClient->GetGUID(strGUID, 0);
        if (nRes == 0) 

⌨️ 快捷键说明

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