コード例 #1
0
ファイル: knmusiccuelistparser.cpp プロジェクト: AnkyoChu/Mu
bool KNMusicCueListParser::parseList(QFile &listFile,
                                     KNMusicListDetailInfo &listDetailInfo)
{
    //Get the file info of the list file.
    QFileInfo listFileInfo(listFile);
    //Initial the file as a text file.
    QTextStream trackStream(&listFile);
    //Read the first text line.
    QString rawLine=trackStream.readLine();
    //Generate the parse cache data.
    QString currentFilePath;            //Current track music file.
    bool inTrack=false;                  //Inside a track or global settings.
    KNMusicListTrackDetailInfo track;   //Track detail info.
    //Check the raw line
    while(!rawLine.isNull())
    {
        //Simplified the line.
        rawLine=rawLine.simplified();
        //Generate command part and data part cache.
        QString rawCommand, rawData;
        //Parse the command.
        parseCommand(rawLine, rawCommand, rawData);
        //Check if command is FILE.
        //In the FILE command, the structure will be like this:
        /*
         * FILE "C:\MYAUDIO.WAV" WAVE
         *  TRACK 01 AUDIO
         *   INDEX 01 00:00:00
         * CATALOG 3898347789120
         * FILE "C:\TRACK2.WAV" WAVE
         *  TRACK 02 AUDIO
         *   INDEX 00 05:49:65  ; 1 second pregap
         *   INDEX 01 05:50:65
         *  TRACK 03 AUDIO
         *   INDEX 00 09:45:50  ; 2 second pregap
         *   INDEX 01 09:47:50
         *  TRACK 04 AUDIO
         *   ISRC ABCDE1234567
         *   INDEX 01 15:12:53
         *  TRACK 05 AUDIO
         *   INDEX 01 25:02:40  ; the track pregap
         *  TRACK 06 AUDIO
         *   TITLE "Stay away"
         *   INDEX 01 27:34:05
         * FILE "TRACK3.WAV" WAVE
         *  TRACK 07 AUDIO
         *   INDEX 01 31:58:53
         *  TRACK 08 AUDIO
         *   INDEX 01 35:08:65
         */
        if(rawCommand=="FILE")
        {
            //Get the file name from the raw data.
            QString filePath=rawLine.left(rawLine.lastIndexOf('\"'));
            filePath.remove(0, filePath.indexOf('\"')+1);
            //Check whether this file is using an absolute path.
            if(QFileInfo::exists(filePath))
            {
                currentFilePath=filePath;
            }
            else
            {
                //It should use a relatively path.
                //Because the cue file is in the same directory of the music
                //file, so we need to combine the music file path.
                filePath=listFileInfo.absoluteDir().filePath(filePath);
                //Check existance.
                if(QFileInfo::exists(filePath))
                {
                    currentFilePath=filePath;
                }
                else
                {
                    //If there's no music file, try to find the music file using
                    //the same name as the cue sheet.
                    filePath=listFileInfo.absoluteDir().filePath(
                                listFileInfo.completeBaseName()+"."+
                                QFileInfo(filePath).suffix());
                    //Check existance.
                    if(!QFileInfo::exists(filePath))
                    {
                        //If we still cannot find the file, then failed to parse
                        //this file.
                        return false;
                    }
                    //Save the file path.
                    currentFilePath=filePath;
                }
            }
            //Update the in file state.
            inTrack=true;
        }
        else if(rawCommand=="TRACK")
        {
            //Check if the previous index is valid.
            if(track.index>-1)
            {
                //Add the previous track to the list.
                listDetailInfo.trackList.append(track);
            }
            //When we get here, means we will have new track.
            //Reset the track detail info.
            track=KNMusicListTrackDetailInfo();
            //Configure the track detail info.
            track.musicFilePath=currentFilePath;
            //The rawData should be like
            //  01 AUDIO
            //The 01 is the track index, get the track index.
            //Use the trackIndex variable find the space temporarily.
            int trackIndex=rawData.indexOf(' ');
            //Get the track index.
            trackIndex=
                    (trackIndex==-1?rawData:rawData.left(trackIndex)).toInt();
            //Check the track index, track index must be start at least 01.
            if(trackIndex>0)
            {
                //Save the track index.
                track.index=trackIndex;
            }
        }
        else if(rawCommand=="INDEX")
        {
            //Check whether we are inside a track, an INDEX command will only
            //available when there's a valid track.
            if(inTrack)
            {
                //Here's the important part, INDEX command record the start
                //time(INDEX 01) and stop time for last track (INDEX 00).
                //Get the current index.
                int indexID=rawData.indexOf(' ');
                QString indexRecord;
                if(indexID!=-1)
                {
                    //Get the index time text.
                    indexRecord=rawData.mid(indexID+1);
                    //Update the index ID.
                    indexID=(indexID==-1?rawData:rawData.left(indexID)).toInt();
                }
                //Check the index ID.
                switch(indexID)
                {
                case -1:    //Invalid.
                    break;
                case 0:     //Stop time for last track.
                {
                    //Check whether there's tracks in the list.
                    if(!listDetailInfo.trackList.isEmpty())
                    {
                        //Get the last track from the list.
                        KNMusicListTrackDetailInfo &lastTrack=
                                listDetailInfo.trackList.last();
                        //Set the duration of the track.
                        lastTrack.trackDuration=
                                textToTime(indexRecord)-lastTrack.startPosition;
                    }
                    break;
                }
                case 1:     //Start time.
                {
                    //Set the start position.
                    track.startPosition=textToTime(indexRecord);
                    //Check the start position.
                    if(track.startPosition==-1)
                    {
                        //Failed to parse the track list.
                        return false;
                    }
                    //Check the previous end duration.
                    //Because the previous one cannot play until to the current
                    //track. If the duration of the previous track is -1, we
                    //need to update the data.
                    //Check whether there's tracks in the list.
                    if(!listDetailInfo.trackList.isEmpty())
                    {
                        //Get the last track from the list.
                        KNMusicListTrackDetailInfo &lastTrack=
                                listDetailInfo.trackList.last();
                        //Set the duration of the track.
                        lastTrack.trackDuration=
                                track.startPosition-lastTrack.startPosition;
                    }
                    break;
                }
                default:
                    break;
                }
            }
        }
        else
        {
            //If the command is not FILE, then it should be metadata.
            /*
             * PERFORMER "BiBi ~ Ayase Eri(Nanjo Yoshino), Nishikino Maki(Pile),
             *                                Yazawa Nico(Tokui Sora) from μ's~"
             * TITLE "Cutie Panther"
             * REM DATE 2013
             * REM DISCID 3507C005
             * REM COMMENT ExactAudioCopy v1.0b2
             */
            //Generate the metadata variable.
            QString metaData;
            //Get the command index and parse the command.
            int commandIndex=parseMetaCommand(rawCommand,
                                              rawData,
                                              metaData,
                                              inTrack);
            //Check the command index, if parse successfully,
            if(commandIndex!=-1)
            {
                if(inTrack && track.index!=-1)
                {
                    //Write the data to the current track.
                    track.metaData.insert(commandIndex, metaData);
                }
                else
                {
                    //Add the current data to list detail info's data.
                    //The later on global variable will over write the previous
                    //one.
                    listDetailInfo.metaData.insert(commandIndex, metaData);
                }
            }
        }
        //Read the next line.
        rawLine=trackStream.readLine();
    }
    //Now the last track is still not be put in the track list.
    //Check if the last track index valid.
    if(track.index>-1)
    {
        //Add the last track to the list.
        listDetailInfo.trackList.append(track);
    }
    //Parse success.
    return true;
}
コード例 #2
0
ファイル: knmusiccueparser.cpp プロジェクト: AG3/Mu
bool KNMusicCueParser::parseList(QFile &listFile,
                                 KNMusicListDetailInfo &listDetailInfo)
{
    //Initial the file as a text file.
    QTextStream trackStream(&listFile);
    //Read the first text line.
    QString rawLine=trackStream.readLine().simplified();
    //Read every line until no text line.
    while(!rawLine.isNull())
    {
        QString rawCommand, rawData;
        parseCommand(rawLine, rawCommand, rawData);
        if(rawCommand=="FILE")
        {
            //Get the file name.
            QString musicFilePath=
                    rawLine.left(rawLine.lastIndexOf('\"'));
            musicFilePath.remove(0, musicFilePath.indexOf('\"')+1);
            //Because the cue file must be the same directory of the music file,
            //so we need to combine the music file path.
            QFileInfo listFileInfo(listFile);
            musicFilePath=listFileInfo.absolutePath()+"/"+musicFilePath;
            //Check is the music file exist.
            QFileInfo musicFileInfo(musicFilePath);
            if(musicFileInfo.exists())
            {
                musicFilePath=musicFileInfo.absoluteFilePath();
            }
            else
            {
                //If there's no music file, try to find the music file using the
                //same name.
                musicFilePath=listFileInfo.absolutePath()+"/"+
                        listFileInfo.completeBaseName()+"."+musicFileInfo.suffix();
                QFileInfo preferMusicFileInfo(musicFilePath);
                if(!preferMusicFileInfo.exists())
                {
                    //If we still can't find this, then is real failed.
                    return false;
                }
                musicFilePath=preferMusicFileInfo.absoluteFilePath();
            }
            //Save the path to listDetailInfo.
            listDetailInfo.musicFilePath=musicFilePath;

            //Now there must all be track data.
            QString trackLine=trackStream.readLine().simplified();
            parseCommand(trackLine, rawCommand, rawData);
            //Do parse until the rawCommand is not "TRACK".
            while(rawCommand=="TRACK" && !trackLine.isNull())
            {
                //Get the current Track Index.
                int trackIndex=rawData.left(rawData.indexOf(' ')).toInt();
                if(trackIndex==0)
                {
                    trackLine=trackStream.readLine();
                    parseCommand(trackLine, rawCommand, rawData);
                    //Read line until the next track.
                    while(rawCommand!="TRACK")
                    {
                        trackLine=trackStream.readLine();
                        parseCommand(trackLine, rawCommand, rawData);
                    }
                    continue;
                }
                //Here must be at least track 01.
                KNMusicListTrackDetailInfo currentTrack;
                //Parse all the data in the track.
                currentTrack.index=trackIndex;
                trackLine=trackStream.readLine().simplified();
                parseCommand(trackLine, rawCommand, rawData);
                while(rawCommand!="TRACK" && !trackLine.isNull())
                {
                    if(rawCommand=="INDEX")
                    {
                        //Here's the important part, INDEX command record the
                        //start time(INDEX 01) and stop time for last track
                        //(INDEX 00).
                        int indexSplitter=rawData.indexOf(' '),
                                indexID=rawData.left(indexSplitter).toInt();
                        QString indexRecordTime=rawData.mid(indexSplitter+1);
                        //Set the track index.
                        switch(indexID)
                        {
                        case 0:
                            //Check is there a track in the list.
                            if(!listDetailInfo.trackList.isEmpty())
                            {
                                listDetailInfo.trackList.last().trackDuration
                                        =timeTextToPosition(indexRecordTime)-
                                         listDetailInfo.trackList.last().startPosition;
                            }
                            break;
                        case 1:
                            //Set the start position.
                            currentTrack.startPosition=
                                    timeTextToPosition(indexRecordTime);
                            //Check is there a track in the list.
                            if(!listDetailInfo.trackList.isEmpty())
                            {
                                if(listDetailInfo.trackList.last().trackDuration==-1)
                                {
                                    //Check the is the last track's track duration
                                    //-1. If so, using the current start as it's
                                    //stop.
                                    listDetailInfo.trackList.last().trackDuration
                                            =currentTrack.startPosition-
                                            listDetailInfo.trackList.last().startPosition;
                                }
                            }
                            //Check is the start position available.
                            if(currentTrack.startPosition==-1)
                            {
                                return false;
                            }
                            break;
                        }
                    }
                    else
                    {
                        int commandIndex;
                        QString commandData;
                        //It must be a metadata.
                        parseMetaCommand(rawCommand,
                                         rawData,
                                         commandIndex,
                                         commandData,
                                         true);
                        //If there's a command we can't parse, that means parse failed.
                        if(commandIndex!=-1)
                        {
                            currentTrack.metaData[commandIndex]=
                                    commandIndex==Comments?
                                        currentTrack.metaData[commandIndex]+commandData:
                                        commandData;
                        }
                    }
                    //Parse next line.
                    trackLine=trackStream.readLine().simplified();
                    parseCommand(trackLine, rawCommand, rawData);
                }
                //Add current track to track list.
                listDetailInfo.trackList.append(currentTrack);
            }
            //If there's no track in the list, means parse failed.
            return listDetailInfo.trackList.size()!=0;
        }
        //This command must be a meta data.
        int commandIndex;
        QString commandData;
        //Parse the current command.
        parseMetaCommand(rawCommand,
                         rawData,
                         commandIndex,
                         commandData,
                         false);
        //If there's a command we can't parse, that means parse failed.
        if(commandIndex!=-1)
        {
            //Add current data to list detail info's data.
            listDetailInfo.metaData[commandIndex]=
                    commandIndex==Comments?
                        listDetailInfo.metaData[commandIndex]+commandData:
                        commandData;
        }
        //Read the next line.
        rawLine=trackStream.readLine().simplified();
    }
    return true;
}