Source

libtaginfo / libtaginfo / trueaudioinfo.cc

Full commit
/*
 * Copyright (C) 2008-2013 J.Rios <anonbeat@gmail.com>
 * Copyright (C) 2013 Jörn Magens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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; see the file LICENSE.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth 
 * Floor, Boston, MA  02110-1301  USA
 * https://www.gnu.org/licenses/lgpl-2.1.txt
 *
 * Author:
 * 	Jörn Magens <shuerhaaken@googlemail.com>
 * 	Matias De lellis <mati86dl@gmail.com>
 * 	Pavel Vasin <rat4vier@gmail.com>
 */


#include "taginfo.h"
#include "taginfo_internal.h"



using namespace TagInfo;



TrueAudioInfo::TrueAudioInfo(const String &filename) : Info(filename) {
    if(!file_name.isEmpty() && !create_file_ref())
        printf("Error creating file ref! %s\n", filename.toCString());
    if(taglib_file) {
        taglib_tagId3v2 = ((TagLib::TrueAudio::File *) taglib_file)->ID3v2Tag(true);
        if(!taglib_tagId3v2 || taglib_tagId3v2->isEmpty()) { // Use fallback for id3v1 or extended header
            //printf("Use fallback! %s\n", filename.toCString(false));
            taglib_tag = ((TagLib::TrueAudio::File *) taglib_file)->tag();
            if(!taglib_tag) {
                printf("Cant get tag object from '%s'\n", file_name.toCString(false));
                valid = false;
            }
        }
    }
    else {
        taglib_tagId3v2 = NULL;
        valid = false;
    }
}


TrueAudioInfo::~TrueAudioInfo() {
}



bool TrueAudioInfo::create_file_ref() {
    if(file_name.isEmpty())
        return false;
    taglib_file = new TagLib::TrueAudio::File(file_name.toCString(false), true, TagLib::AudioProperties::Fast);
    if(taglib_file) {
        return true;
    }
    else {
        printf("TagLib::File creation failed for '%s'\n", file_name.toCString(false));
        return false;
    }
}


bool TrueAudioInfo::read(void) {
    if(Info::read()) {
        if(taglib_tagId3v2 && !taglib_tagId3v2->isEmpty()) {
            if(!taglib_tag)
                read_virtual_tags((TagLib::Tag *)taglib_tagId3v2);
            if(taglib_tagId3v2->frameListMap().contains("TPOS")) {
                disk_number = 
                    atol(taglib_tagId3v2->frameListMap()[ "TPOS" ].front()->toString().toCString(false));
                if(disk_number < 1)
                    disk_number = 1;
            }
            if(taglib_tagId3v2->frameListMap().contains("TCOM")) {
                composer = taglib_tagId3v2->frameListMap()[ "TCOM" ].front()->toString();
            }
            if(taglib_tagId3v2->frameListMap().contains("TPE2")) {
                album_artist = taglib_tagId3v2->frameListMap()[ "TPE2" ].front()->toString();
            }
            if(taglib_tagId3v2->frameListMap().contains("TCMP")) {
                is_compilation = taglib_tagId3v2->frameListMap()[ "TCMP" ].front()->toString() == String("1");
            }
            TagLib::ID3v2::PopularimeterFrame * popularity_frame = NULL;

            popularity_frame = get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
            if(!popularity_frame)
                popularity_frame = get_popularity_frame(taglib_tagId3v2, "");
            if(popularity_frame) {
                rating = popularity_to_rating(popularity_frame->rating());
                playcount = popularity_frame->counter();
            }
            if(track_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "TRACK_LABELS");
                if(!frame)
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "TRACKLABELS");
                if(frame) {
                    track_labels_string = frame->fieldList()[1];
                    track_labels = split(track_labels_string, "|");
                }
            }
            if(artist_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = 
                    ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ARTIST_LABELS");
                if(!frame)
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ARTISTLABELS");
                if(frame) {
                    artist_labels_string = frame->fieldList()[1];
                    artist_labels = split(artist_labels_string, "|");
                }
            }
            if(album_labels.size() == 0) {
                ID3v2::UserTextIdentificationFrame * frame = 
                    ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ALBUM_LABELS");
                    frame = ID3v2::UserTextIdentificationFrame::find(taglib_tagId3v2, "ALBUMLABELS");
                if(frame) {
                    album_labels_string = frame->fieldList()[1];
                    album_labels = split(album_labels_string, "|");
                }
            }
            TagLib::ID3v2::FrameList frameList = taglib_tagId3v2->frameListMap()["APIC"];
            has_image = (frameList.size() > 0);
        }
    }
    else {
        printf("Error: Could not read tags from file '%s'\n", file_name.toCString(true));
        return false; 
    }
    return true;
}


bool TrueAudioInfo::write(void) {
    if(taglib_tagId3v2) {
        if(changedflag) {
            TagLib::ID3v2::TextIdentificationFrame * frame;
            if(changedflag & CHANGED_DATA_DISK_NUM) {
                taglib_tagId3v2->removeFrames("TPOS");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TPOS");
                frame->setText(format("%u", disk_number));
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_COMPOSER_TAG) {
                taglib_tagId3v2->removeFrames("TCOM");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TCOM");
                frame->setText(composer);
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_DATA_ALBUMARTIST) {
                taglib_tagId3v2->removeFrames("TPE2");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TPE2");
                frame->setText(album_artist);
                taglib_tagId3v2->addFrame(frame);
            }
            if(changedflag & CHANGED_IS_COMPILATION_TAG) {
                taglib_tagId3v2->removeFrames("TCMP");
                frame = new TagLib::ID3v2::TextIdentificationFrame("TCMP");
                if(is_compilation) {
                    frame->setText("1");
                }
                else {
                    frame->setText("0");
                }
                taglib_tagId3v2->addFrame(frame);
            }
            // I have found several TRCK fields in the mp3s
            if(changedflag & CHANGED_TRACKNO_TAG) {
                taglib_tagId3v2->removeFrames("TRCK");
                taglib_tagId3v2->setTrack(tracknumber);
            }
            TagLib::ID3v2::PopularimeterFrame * popularity_frame;
            if(changedflag & CHANGED_DATA_RATING) {
                popularity_frame = 
                    get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
                if(!popularity_frame) {
                    popularity_frame = new TagLib::ID3v2::PopularimeterFrame();
                    taglib_tagId3v2->addFrame(popularity_frame);
                    popularity_frame->setEmail("LibTagInfo");
                }
                if(popularity_frame)
                    popularity_frame->setRating(rating_to_popularity(rating));
            }
            if(changedflag & CHANGED_DATA_PLAYCOUNT) {
                if(!popularity_frame)
                    popularity_frame = get_popularity_frame(taglib_tagId3v2, "LibTagInfo");
                if(!popularity_frame) {
                    popularity_frame = new TagLib::ID3v2::PopularimeterFrame();
                    taglib_tagId3v2->addFrame(popularity_frame);
                    popularity_frame->setEmail("LibTagInfo");
                }
                if(popularity_frame)
                    popularity_frame->setCounter(playcount);
            }
            
            // The Labels
            if(changedflag & CHANGED_TRACK_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "TRACK_LABELS", track_labels_string);
            if(changedflag & CHANGED_ARTIST_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "ARTIST_LABELS", artist_labels_string);
            if(changedflag & CHANGED_ALBUM_LABELS)
                id3v2_check_label_frame(taglib_tagId3v2, "ALBUM_LABELS", album_labels_string);
            
            
            write_virtual_tags((TagLib::Tag *)taglib_tagId3v2);
        }
    }
    return Info::write();
}


bool TrueAudioInfo::can_handle_images(void) const {
    return true;
}

bool TrueAudioInfo::get_image(char*& data, int &data_length, ImageType &image_type) const {
    if(taglib_tagId3v2)
        return get_id3v2_image(taglib_tagId3v2, data, data_length, image_type);
    return false;
}

bool TrueAudioInfo::set_image(const char* data, int data_length, ImageType image_type) {
    if(taglib_tagId3v2)
        set_id3v2_image(taglib_tagId3v2, data, data_length, image_type);
    return true;
}

bool TrueAudioInfo::can_handle_lyrics(void) const {
    return true;
}


String TrueAudioInfo::get_lyrics(void) const {
    if(taglib_tagId3v2) {
        return get_id3v2_lyrics(taglib_tagId3v2);
    }
    return String();
}


bool TrueAudioInfo::set_lyrics(const String &lyrics) {
    if(taglib_tagId3v2) {
        set_id3v2_lyrics(taglib_tagId3v2, lyrics);
        return true;
    }
    return false;
}