bool TagReader::read()
{
    // TagLib functions are not reentrant
    QMutexLocker locker(&m_mutex);

    QByteArray encodedFileName = QFile::encodeName(m_fileName);
	TagLib::FileRef file(encodedFileName.constData(), true);
	if (file.isNull()) {
		return false;
    }

	TagLib::Tag *tags = file.tag();	
	TagLib::AudioProperties *props = file.audioProperties();
	if (!tags || !props) {
        return false;
    }

	m_length = props->length();
    m_bitrate = props->bitrate();
	m_mbid = extractMusicBrainzTrackID(file.file());
	if (!m_length || m_mbid.size() != 36) {
		return false;
    }

    return true;
}
Example #2
0
AlbumTrack::AlbumTrack(Album* album, QString trackPath)
{
    this->path = trackPath;
    this->number = 0;
    this->artist = "Unknown Artist";
    this->album = album;
    this->genre = "Unknown Genre";

    TagLib::FileRef f(trackPath.toStdString().c_str());
    if(!f.isNull() && f.tag())
    {
        TagLib::Tag *tag = f.tag();
        title = QString(tag->title().toCString());
        number = tag->track();
        artist = QString(tag->artist().toCString());
        albumName = QString(tag->album().toCString());
        genre = QString(tag->genre().toCString());
    }
    if(!f.isNull() && f.audioProperties())
    {
        TagLib::AudioProperties *properties = f.audioProperties();
        duration = properties->length() * 1000;
        //Weil Fmod die gerne in Millisekunden hätte
    }
}
Example #3
0
int main(int argc, char *argv[])
{
  for(int i = 1; i < argc; i++) {

    cout << "path:" << argv[i] << endl;

    TagLib::FileRef f(argv[i]);

    if(!f.isNull() && f.tag()) {

      TagLib::Tag *tag = f.tag();

      cout << "title:" << (tag->title()).toCString(true)   << endl;
      cout << "artist:" << (tag->artist()).toCString(true) << endl;
      cout << "album:" << (tag->album()).toCString(true)   << endl;
      cout << "albumartist:" << (tag->albumArtist()).toCString(true) << endl;
      cout << "track:" << tag->track() << endl;
      cout << "disc:"  << tag->cdNr() << endl;
    }

    if(!f.isNull() && f.audioProperties()) {

      TagLib::AudioProperties *properties = f.audioProperties();

      cout << "bitrate:" << properties->bitrate() << endl;
      cout << "length:" << properties->length()  << endl;
    }
  if(i!=argc-1)
    cout << "---" << endl;
  }
  return 0;
}
Example #4
0
Tune* tuneFromFile(const QString& file)
{
	Tune* tune = new Tune(false);
	tune->file = file;

	TagLib::FileRef ref = fileName2TaglibRef(file);
	if(!ref.isNull()) {
		if(ref.tag()) {
			TagLib::Tag* tag = ref.tag();
			tune->artist = safeTagLibString2QString( tag->artist() );
			tune->album = safeTagLibString2QString( tag->album() );
			tune->title = safeTagLibString2QString( tag->title() );
			tune->trackNumber = QString::number( tag->track() );
			tune->genre = safeTagLibString2QString( tag->genre() );
		}

		Qomp::loadCover(tune, ref.file());

		if(ref.audioProperties()) {
			TagLib::AudioProperties *prop = ref.audioProperties();
			tune->duration = Qomp::durationSecondsToString( prop->length() );
			tune->bitRate = QString::number( prop->bitrate() );
		}

		tune->setMetadataResolved(true);
	}

	return tune;
}
Example #5
0
int handle_file(const char* filepath, const char* filekey, AudioFileRecordStore& record_store)
{
    bool record_exists = record_store.find_record(filekey) != NULL;

    // Scanning a file for tags is expensive, so only do it if required.
    if(record_exists
            && !record_store.record_update_required(filekey))
    {
        // no update reqquired so has been handled.
        return 1;
    }

    TagLib::FileRef f(filepath);
    if (!f.isNull() && f.tag())
    {
        AudioFileRecord &record = record_store.get_record(filekey);
        record.update_start();

        if (verbose)
        {
            TagLib::Tag *tag = f.tag();
            std::cout << filepath << endl;
            std::cout << filekey << endl;
            std::cout << "-- TAG (basic) --" << endl;
            std::cout << "title   - \"" << tag->title()   << "\"" << endl;
            std::cout << "artist  - \"" << tag->artist()  << "\"" << endl;
            std::cout << "album   - \"" << tag->album()   << "\"" << endl;
            std::cout << "year    - \"" << tag->year()    << "\"" << endl;
            std::cout << "comment - \"" << tag->comment() << "\"" << endl;
            std::cout << "track   - \"" << tag->track()   << "\"" << endl;
            std::cout << "genre   - \"" << tag->genre()   << "\"" << endl;
        }

        TagLib::PropertyMap tags = f.file()->properties();

        for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i)
        {
            for(TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) 
            {
                record.update(i->first.toCString(true), j->toCString(true));
            }
        }

        if (f.audioProperties())
        {
            TagLib::AudioProperties *properties = f.audioProperties();
            record.update(audio_tags::BITRATE, properties->bitrate());
            record.update(audio_tags::LENGTH, properties->length());
            record.update(audio_tags::SAMPLERATE, properties->sampleRate());
            record.update(audio_tags::CHANNELS, properties->channels());
        }

        record.update_complete();
        return 1;
    }

    return 0;
}
Example #6
0
bool ReadTag(const musik::Core::String& fn, musik::Core::SongInfo& target)
{
    bool ret = true;

    musik::Core::Filename mfn(fn);

    target.SetFilename(fn);
    target.SetFormat("Ogg Vorbis");

    try
    {
#if defined (WIN32)
        TagLib::FileRef tag_file(fn.c_str());
#else    
        TagLib::FileRef tag_file(utf16to8(fn, true).c_str());
#endif
        if (!tag_file.isNull())
        {
            if (tag_file.tag())
            {
                TagLib::Tag *tag = tag_file.tag();        

                target.SetArtist(musik::Core::utf8to16(tag->artist().to8Bit(true)));
                target.SetAlbum(musik::Core::utf8to16(tag->album().to8Bit(true)));
                target.SetTitle(musik::Core::utf8to16(tag->title().to8Bit(true)));
                target.SetGenre(musik::Core::utf8to16(tag->genre().to8Bit(true)));
                target.SetNotes(musik::Core::utf8to16(tag->comment().to8Bit(true)));

                target.SetYear(musik::Core::IntToString(tag->year()));
                target.SetTrackNum(musik::Core::IntToString(tag->track()));
            }

            if (tag_file.audioProperties())
            {
                TagLib::AudioProperties *properties = tag_file.audioProperties();
                int duration = properties->length() * 1000;
                target.SetBitrate(musik::Core::IntToString(properties->bitrate()));
                target.SetDuration(musik::Core::IntToString(duration));
            }
        }

        // if the title is empty, then use the
        // filename...
        if (target.GetTitle().IsEmpty())
        {
            musik::Core::Filename MFN(fn);
            target.SetTitle(MFN.GetJustFilename());
        }
    }
    catch (...)
    {
        ret = false;
        cout << "taglib crashed reading: " << fn.c_str() << endl;
    }

    return ret;
}
Example #7
0
bool MetaData(const char* filepath, cFields& fields, cRow& props)
{
#define ADD(x, t) do { if (t) { fields.push_back(x); props.push_back(t); } } while(0)
#define ADDSTRING(x, t) do { if (!t.empty()) { fields.push_back(x); props.push_back(t); } } while(0)
#define ADDINT(x, t) do { std::string c = *itoa(t); if (!c.empty()){ fields.push_back(x); props.push_back(c);} } while(0)
    
    TagLib::FileRef f(filepath);

    fields.clear();
    props.clear();

    //cTag t;
    //const char* tmp = NULL;
    std::string tmp;
    
    if (f.isNull()) 
    {
        std::cerr<< "Taglib failed on " << filepath << std::endl;
        ADD("metadata_needs_update", "2"); // failure
        return false;
    }
   
    TagLib::Tag *tag = f.tag();
    
    if (tag) 
    {
#if 0
      tmp   = toString(tag->title()).c_str();   ADD("title",   tmp);
      tmp   = toString(tag->artist()).c_str();  ADD("artist",  tmp);
      tmp   = toString(tag->album()).c_str();   ADD("album",   tmp);
      tmp   = toString(tag->comment()).c_str(); ADD("comment", tmp);
      tmp   = toString(tag->genre()).c_str();   ADD("genre",   tmp);
#else
        tmp   = toString(tag->title());   ADDSTRING("title",   tmp);
        tmp   = toString(tag->artist());  ADDSTRING("artist",  tmp);
        tmp   = toString(tag->album());   ADDSTRING("album",   tmp);
        tmp   = toString(tag->comment()); ADDSTRING("comment", tmp);
        tmp   = toString(tag->genre());   ADDSTRING("genre",   tmp);
#endif
      
      //ADDINT("track", tag->track());
      ADDINT("year",  tag->year());
    }
    
    TagLib::AudioProperties *prop = f.audioProperties();
    if (prop) 
    {
        ADDINT("bitrate",    prop->bitrate());
        ADDINT("samplerate", prop->sampleRate());
      //  ADDINT("channels",   prop->channels());
        ADDINT("length" ,    prop->length());
    }
 
    ADD("metadata_needs_update", "0");
    return true;
}
Example #8
0
bool getAudioInfo(const QString& file, qint64* durationMiliSecs, int* bitrate)
{
	TagLib::FileRef ref = Qomp::fileName2TaglibRef(file);
	if(!ref.isNull() && ref.audioProperties()) {
		TagLib::AudioProperties *prop = ref.audioProperties();

		*bitrate = prop->bitrate();
		*durationMiliSecs = prop->length() * 1000;

		return true;
	}

	return false;
}
Example #9
0
void designer::getFiles(QStringList files)
{
    if (files.empty())
        return;

    QString filenames = "";
    int duration = 0;
    foreach(QString filepath, files)
    {
        TagLib::FileRef f(reinterpret_cast<filestr*>(filepath.constData()));
        TagLib::AudioProperties* props = f.audioProperties();
        duration += props->lengthInSeconds();

        QString filename = filepath.split("/").last();
        filename.remove(QRegExp("\\.(mp3|flac|m4a)"));
        filenames += filename + "\n";
    }
string scan_file(const char* path)
{
    TagLib::FileRef f(path);
    if (!f.isNull() && f.tag()) {
        TagLib::Tag *tag = f.tag();
        int filesize = boost::filesystem::file_size(path);
        int bitrate = 0;
        int duration = 0;
        if (f.audioProperties()) {
            TagLib::AudioProperties *properties = f.audioProperties();
            duration = properties->length();
            bitrate = properties->bitrate();
        }
        string artist = tag->artist().toCString(true);
        string album  = tag->album().toCString(true);
        string track  = tag->title().toCString(true);
        boost::trim(artist);
        boost::trim(album);
        boost::trim(track);
        if (artist.length()==0 || track.length()==0) {
            return "{\"error\" : \"no tags\"}\n";
        }
        string ext(toUtf8(boost::filesystem::extension(path)));
        string mimetype = ext2mime(boost::to_lower_copy(ext));
        // turn it into a url by prepending file://
        // because we pass all urls to curl:
        string urlpath = urlify( toUtf8(path) );

        ostringstream os;
        os      <<  "{  \"url\" : \"" << urlpath << "\","
                    "   \"filesize\" : " << filesize << ","
                    "   \"mimetype\" : \"" << mimetype << "\","
                    "   \"artist\" : \"" << tidy(artist) << "\","
                    "   \"album\" : \"" << tidy(album) << "\","
                    "   \"track\" : \"" << tidy(track) << "\","
                    "   \"duration\" : " << duration << ","
                    "   \"bitrate\" : " << bitrate << ","
                    "   \"trackno\" : " << tag->track()

                <<  "}\n";
        return os.str();
    }
    return "{\"error\" : \"no tags\"}\n";
}
string scan_file(const char* path)
{
    TagLib::FileRef f(path);
    if (!f.isNull() && f.tag()) {
        TagLib::Tag *tag = f.tag();
        int bitrate = 0;
        int duration = 0;
        if (f.audioProperties()) {
            TagLib::AudioProperties *properties = f.audioProperties();
            duration = properties->length();
            bitrate = properties->bitrate();
        }
        string artist = tag->artist().toCString(true);
        string album  = tag->album().toCString(true);
        string track  = tag->title().toCString(true);
        trim(artist);
        trim(album);
        trim(track);
        if (artist.length()==0 || track.length()==0) {
            return "{\"error\" : \"no tags\"}";
        }
        string pathstr(path);
        string ext = pathstr.substr(pathstr.length()-4);
        std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
        string mimetype = ext2mime(ext);
        // turn it into a url by prepending file://
        // because we pass all urls to curl:
        string urlpath = urlify( path );

        ostringstream os;
        os      <<  "{  \"url\" : \"" << esc(urlpath) << "\","
                    "   \"mimetype\" : \"" << mimetype << "\","
                    "   \"artist\" : \"" << tidy(artist) << "\","
                    "   \"album\" : \"" << tidy(album) << "\","
                    "   \"track\" : \"" << tidy(track) << "\","
                    "   \"duration\" : " << duration << ","
                    "   \"bitrate\" : " << bitrate << ","
                    "   \"trackno\" : " << tag->track()
                <<  "}";
        return os.str();
    }
    return "{\"error\" : \"no tags\"}";
}
Example #12
0
void getMp3Info(const WCHAR* fileName, MP3Info &info)
{
    TagLib::FileRef f(fileName);

    if (!f.isNull() && f.tag())
    {
        TagLib::Tag *tag = f.tag();

        info.tag[0] = tag->title().toWString();
        info.tag[1] = tag->artist().toWString();
        info.tag[2] = tag->album().toWString();
        info.tag[3] = tag->comment().toWString();
        info.tag[4] = tag->genre().toWString();
        info.year = tag->year();
        info.track = tag->track();

        TagLib::PropertyMap tags = f.file()->properties();

        if (!f.isNull() && f.audioProperties()) 
        {
            TagLib::AudioProperties *properties = f.audioProperties();

            int seconds = properties->length() % 60;
            int minutes = (properties->length() - seconds) / 60;

            info.bitrate = properties->bitrate();
            info.sample_rate = properties->sampleRate();
            info.channels = properties->channels();
            info.length_minutes = minutes;
            info.length_seconds = seconds;
        }
    }
}
Example #13
0
// Use Taglib to parse tags from file and add entried to wxListCtrl
void AddFromFile_Taglib(wxListCtrl *listctrl, const std::map< wxString, long > &mapping, const wxString &filename)
{
    TagLib::FileRef f = TagLib::FileRef(filename.c_str(), TagLib::String::UTF8 ); //TODO: is c_str() safe?

    if ( f.isNull() )
    {
        wxLogError(wxT("Error: TagLib could not read ") + filename + wxT("."));
        return;
    }

    if ( ! f.tag() )
    {
        wxLogError(wxT("Error: TagLib could not read the tags of file ") + filename + wxT("."));
        return;
    }

    TagLib::Tag *tag = f.tag();
    auto idx = listctrl->GetItemCount();
    auto row_idx = listctrl->InsertItem(idx, wxString::Format(wxT("%d"), idx) );

    // TODO: check return values
    listctrl->SetItem(row_idx, mapping.find("Artist")->second, wxString(tag->artist().to8Bit(true)) );
    listctrl->SetItem(row_idx, mapping.find("Trackname")->second, wxString(tag->title().to8Bit(true)));
    listctrl->SetItem(row_idx, mapping.find("Album")->second, wxString(tag->album().to8Bit(true)));

    if ( f.audioProperties() )
    {
      TagLib::AudioProperties *properties = f.audioProperties();
      int seconds = properties->length() % 60;
      int minutes = (properties->length() - seconds) / 60;

      wxString timestr = wxString::Format("%d:%02d", minutes, seconds);

      listctrl->SetItem(row_idx, mapping.find("Time")->second, timestr);
    }

}
Example #14
0
bool ReadTags(const string &filename, bool ignore_missing_mbid)
{
	TagLib::FileRef file(filename.c_str(), true);
	if (file.isNull())
		return false;
	TagLib::Tag *tags = file.tag();	
	TagLib::AudioProperties *props = file.audioProperties();
	if (!tags || !props)
		return false;
	//cout << "ARTIST=" << tags->artist().to8Bit(true) << "\n";
	//cout << "TITLE=" << tags->title().to8Bit(true) << "\n";
	//cout << "ALBUM=" << tags->album().to8Bit(true) << "\n";
	int length = props->length();
	if (!length)
		return false;
	string mbid = ExtractMusicBrainzTrackID(file.file());
	if (mbid.size() != 36 && !ignore_missing_mbid)
		return false;
	if (mbid.size() == 36)
		cout << "MBID=" << mbid << "\n";
	cout << "LENGTH=" << length << "\n";
	cout << "BITRATE=" << props->bitrate() << "\n";
	return true;
}
Example #15
0
int main(int argc, char *argv[])
{
  for(int i = 1; i < argc; i++) {

    cout << "******************** \"" << argv[i] << "\" ********************" << endl;

    TagLib::FileRef f(argv[i]);

    if(!f.isNull() && f.tag()) {

      TagLib::Tag *tag = f.tag();

      cout << "-- TAG (basic) --" << endl;
      cout << "title   - \"" << tag->title()   << "\"" << endl;
      cout << "artist  - \"" << tag->artist()  << "\"" << endl;
      cout << "album   - \"" << tag->album()   << "\"" << endl;
      cout << "year    - \"" << tag->year()    << "\"" << endl;
      cout << "comment - \"" << tag->comment() << "\"" << endl;
      cout << "track   - \"" << tag->track()   << "\"" << endl;
      cout << "genre   - \"" << tag->genre()   << "\"" << endl;

      TagLib::PropertyMap tags = f.file()->properties();

      unsigned int longest = 0;
      for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) {
        if (i->first.size() > longest) {
          longest = i->first.size();
        }
      }

      cout << "-- TAG (properties) --" << endl;
      for(TagLib::PropertyMap::ConstIterator i = tags.begin(); i != tags.end(); ++i) {
        for(TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) {
          cout << left << std::setw(longest) << i->first << " - " << '"' << *j << '"' << endl;
        }
      }

    }

    if(!f.isNull() && f.audioProperties()) {

      TagLib::AudioProperties *properties = f.audioProperties();

      int seconds = properties->length() % 60;
      int minutes = (properties->length() - seconds) / 60;

      cout << "-- AUDIO --" << endl;
      cout << "bitrate     - " << properties->bitrate() << endl;
      cout << "sample rate - " << properties->sampleRate() << endl;
      cout << "channels    - " << properties->channels() << endl;
      cout << "length      - " << minutes << ":" << setfill('0') << setw(2) << seconds << endl;
    }
  }
  return 0;
}
Example #16
0
int main(int argc, char *argv[])
{
    for(int i = 1; i < argc; i++) {

        cout << "******************** \"" << argv[i] << "\" ********************" << endl;

        TagLib::FileRef f(argv[i]);

        if(!f.isNull() && f.tag()) {

            TagLib::Tag *tag = f.tag();

            cout << "-- TAG --" << endl;
            cout << "title   - \"" << tag->title()   << "\"" << endl;
            cout << "artist  - \"" << tag->artist()  << "\"" << endl;
            cout << "album   - \"" << tag->album()   << "\"" << endl;
            cout << "year    - \"" << tag->year()    << "\"" << endl;
            cout << "comment - \"" << tag->comment() << "\"" << endl;
            cout << "track   - \"" << tag->track()   << "\"" << endl;
            cout << "genre   - \"" << tag->genre()   << "\"" << endl;
        }

        if(!f.isNull() && f.audioProperties()) {

            TagLib::AudioProperties *properties = f.audioProperties();

            int seconds = properties->length() % 60;
            int minutes = (properties->length() - seconds) / 60;

            cout << "-- AUDIO --" << endl;
            cout << "bitrate     - " << properties->bitrate() << endl;
            cout << "sample rate - " << properties->sampleRate() << endl;
            cout << "channels    - " << properties->channels() << endl;
            cout << "length      - " << minutes << ":" << formatSeconds(seconds) << endl;
        }
    }
    return 0;
}
Example #17
0
bool mediaTag(Artwork *art, TagLib::File *f)
{
    Q_ASSERT(f != NULL);
    Q_ASSERT(f->tag());

    TagLib::Tag *tag = f->tag();
    art->filetype = FILETYPE_UNKNOWN;

    // The basic stuff!!!
    art->artist = TStringToQString(tag->artist()).trimmed();
    art->album = TStringToQString(tag->album()).trimmed();
    art->track = TStringToQString(tag->title()).trimmed();
    art->genre = TStringToQString(tag->genre()).trimmed();
    art->year = tag->year();
    art->trackNo = tag->track();

    // we need something to search on!
    if (art->artist == "" && art->album == "" && art->track == "") {
        return false;
    }

    // Any audio properties???
    if (f->audioProperties()) {
        TagLib::AudioProperties *properties = f->audioProperties();

        int seconds = properties->length() % 60;
        int minutes = (properties->length() - seconds) / 60;
        art->duration = minutes * 60 + seconds;

        art->bitRate = properties->bitrate();
        art->sampleRate = properties->sampleRate();
        art->channels = properties->channels();
    }

    art->makeSearchable();
    return true;
}
Example #18
0
std::vector<std::string> GetFileInfo(std::string path)
{
	std::vector<std::string> fileInfo;
	std::string title, artist, album, genre, comment;

	TagLib::FileRef f( path.c_str() );
	if(!f.isNull() && f.tag())
	{
		TagLib::Tag *tag = f.tag();
								 // unicode = false
		title   = tag->title().stripWhiteSpace().toCString(false)  ;
		if(title.size())
		{
			std::stringstream temp;
			temp << tr("Title") << ":\t";
			temp << title;
			fileInfo.push_back(temp.str());
		}

		artist  = tag->artist().stripWhiteSpace().toCString(false) ;
		if(artist.size())
		{
			std::stringstream temp;
			temp << tr("Artist") << ":\t";
			temp << artist;
			fileInfo.push_back(temp.str());
		}

		album   = tag->album().stripWhiteSpace().toCString(false)  ;
		if(album.size())
		{
			std::stringstream temp;
			temp << tr("Album") << ":\t";
			temp << album;
			fileInfo.push_back(temp.str());
		}

		genre   = tag->genre().stripWhiteSpace().toCString(false)  ;
		if(genre.size())
		{
			std::stringstream temp;
			temp << tr("Genre") << ":\t";
			temp << genre;
			fileInfo.push_back(temp.str());
		}

		comment   = tag->comment().stripWhiteSpace().toCString(false)  ;
		if(comment.size())
		{
			std::stringstream temp;
			temp << tr("Comment") << ":\t";
			temp << comment;
			fileInfo.push_back(temp.str());
		}

		if(tag->year())
		{
			std::stringstream temp;
			temp << tr("Year") << ":\t";
			temp << tag->year();
			fileInfo.push_back(temp.str());
		}

		if(tag->track())
		{
			std::stringstream temp;
			temp << tr("Track") << ":\t";
			temp << tag->track();
			fileInfo.push_back(temp.str());
		}
	}

	if(!f.isNull() && f.audioProperties())
	{
		TagLib::AudioProperties *props = f.audioProperties();
		if(props->length())
		{
			int min = props->length()/60;
			int sec = props->length()%60;
			std::stringstream temp;
			temp << tr("Length") << ":\t";
			temp << min << ":";
			if(sec<=9)
				temp << "0";
			temp << sec << " " << tr("min");
			fileInfo.push_back(temp.str());
		}

		if(props->bitrate())
		{
			std::stringstream temp;
			temp << tr("Bitrate") << ":\t";
			temp << props->bitrate() << " kb/s";
			fileInfo.push_back(temp.str());
		}

		if(props->sampleRate())
		{
			std::stringstream temp;
			temp << tr("Samplerate") << ":\t";
			temp << props->sampleRate() << " Hz";
			fileInfo.push_back(temp.str());
		}

		if(props->channels())
		{
			std::stringstream temp;
			temp << tr("ID3$Channels") << ":\t";
			temp << props->channels();
			fileInfo.push_back(temp.str());
		}

		if(TagLib::MPEG::Properties* mpegProp = dynamic_cast<TagLib::MPEG::Properties*>(props))
		{
			#if 0
			std::stringstream temp;
			temp << tr("Original") << ":\t";
			temp << mpegProp->isOriginal();
			fileInfo.push_back(temp.str());
			#endif
			std::stringstream temp2;
			temp2 << tr("MPEG-Layer") << ":\t";
			temp2 << mpegProp->layer();
			fileInfo.push_back(temp2.str());
			#if 0
			std::stringstream temp3;
			temp3 << tr("Copyrighted") << ":\t";
			temp3 << mpegProp->isCopyrighted();
			fileInfo.push_back(temp3.str());

			std::stringstream temp4;
			temp4 << tr("Protected") << ":\t";
			temp4 << mpegProp->protectionEnabled();
			fileInfo.push_back(temp4.str());
			#endif
		}
	}

	struct stat stats;
	if(stat(path.c_str(), &stats) == 0)
	{
		std::stringstream temp;
		char buf[32];
		temp << tr("File size") << ":\t";
		if(stats.st_size < 1024)
		{
			temp << stats.st_size << " B";
		}
		else if (stats.st_size < 1024*1024)
		{
			sprintf(buf, "%0.1f", ((float)stats.st_size)/1024);
			temp << buf << " KB";
		}
		else
		{
			sprintf(buf, "%0.1f", ((float)stats.st_size)/(1024*1024));
			temp << buf << " MB";
		}
		fileInfo.push_back(temp.str());

		std::stringstream temp2;
		temp2 << tr("Last Modified") << ":\t";
		temp2 << ctime(&stats.st_mtime);
                // remove '\n'
                std::string time_str = temp2.str();
                if (time_str.length()>0 && time_str.at(time_str.length()-1) == '\n')
                    time_str = time_str.substr(0,time_str.length()-1);
		fileInfo.push_back(time_str);
	}

	return fileInfo;
}
Example #19
0
int main(int argc, char *argv[])
{
  for(int i = 1; i < argc; i++) {

    cout << "******************** \"" << argv[i] << "\" ********************" << endl;

    TagLib::FileRef f(argv[i]);

    if(!f.isNull() && f.tag()) {

      TagLib::Tag *tag = f.tag();

      cout << "-- TAG --" << endl;
      cout << "title        - \"" << tag->title()   << "\"" << endl;
      cout << "artist       - \"" << tag->artist()  << "\"" << endl;
      cout << "album artist - \"" << tag->albumArtist()   << "\"" << endl;
      cout << "album        - \"" << tag->album()   << "\"" << endl;
      cout << "year         - \"" << tag->year()    << "\"" << endl;
      cout << "comment      - \"" << tag->comment() << "\"" << endl;
      cout << "track        - \"" << tag->track()   << "\"" << endl;
      cout << "genre        - \"" << tag->genre()   << "\"" << endl;
      cout << "grouping     - \"" << tag->grouping()   << "\"" << endl;
      TagLib::Ogg::XiphComment *comment = NULL;
      TagLib::FLAC::File *flac = dynamic_cast<TagLib::FLAC::File *>(f.file());
      if (flac) {
        cout << "flac:" << endl;
        cout << "id3v1   - \"" << flac->ID3v1Tag()   << "\"" << endl;
        cout << "id3v2   - \"" << flac->ID3v2Tag()   << "\"" << endl;
        cout << "xiph    - \"" << flac->xiphComment()   << "\"" << endl;
        comment = flac->xiphComment();
      }
      if (!comment) {
        comment = dynamic_cast<TagLib::Ogg::XiphComment *>(tag);
      }
      if (comment) {
        TagLib::Ogg::FieldListMap fields = comment->fieldListMap();
        for(TagLib::Ogg::FieldListMap::ConstIterator it = fields.begin(), end = fields.end(); it != end; it++) {
          if (!it->second.isEmpty())
            cout << "xiph:" << it->first << " \"" << it->second[0].substr(0,3) << "\"" << endl;
        }
      }
      cout << "pictures- \"" << f.file()->pictures().size()   << "\"" << endl;
      TagLib::File::PictureList l = f.file()->pictures();
      for (TagLib::File::_PictureList::ConstIterator i = l.begin(), end = l.end(); i != end; i++) {
        cout << "\t" << (*i)->typeName() << ' ' << (*i)->mimeType() << ' ' << (*i)->base64data().size() << endl;
      }
      
      cout << "pictures- \"" << tag->pictures().size()   << "\"" << endl;
    }

    if(!f.isNull() && f.audioProperties()) {

      TagLib::AudioProperties *properties = f.audioProperties();

      int seconds = properties->length() % 60;
      int minutes = (properties->length() - seconds) / 60;

      cout << "-- AUDIO --" << endl;
      cout << "bitrate     - " << properties->bitrate() << endl;
      cout << "sample rate - " << properties->sampleRate() << endl;
      cout << "channels    - " << properties->channels() << endl;
      cout << "length      - " << minutes << ":" << formatSeconds(seconds) << endl;
    }
  }
  return 0;
}
Example #20
0
void RecurseWorker::updateTrackInfo( const TrackInfo &trackInfo )
{
   bool tagsChanged     = false;
   TrackInfo ti         = trackInfo;
   TrackInfo oldTags;
   QString oldpath( trackInfo.mDirectory + "/" + trackInfo.mFileName );

   mTagMap.clear();
   {
      TagLib::FileRef f( oldpath.toLocal8Bit().data() );
      if( f.file() )
      {
         oldTags = trackInfo;

         TagLib::AudioProperties *audioProperties = f.audioProperties();
         TagLib::Tag *tag = f.tag();
         if( audioProperties )
         {
            oldTags.mPlayTime = audioProperties->length();
         }
         if( tag )
         {
            oldTags.mArtist  = QString::fromUtf8( tag->artist().toCString( true ) );
            oldTags.mTitle   = QString::fromUtf8( tag->title().toCString( true ) );
            oldTags.mAlbum   = QString::fromUtf8( tag->album().toCString( true ) );
            oldTags.mTrackNr = tag->track();
            oldTags.mYear    = tag->year();
            oldTags.mGenre   = QString::fromUtf8( tag->genre().toCString( true ) );
         }
         else
         {
            emit error( tr("Could not read tags"), oldpath );
         }
         ti = oldTags;
      }
      else
      {
         emit error( tr("Could not read file"), oldpath );
      }
   }

   switch( mMode )
   {
   case ModeSetTags:
      if( mSetArtist )
      {
         ti.mArtist = mTrackInfo.mArtist;
      }
      if( mSetTitle )
      {
         ti.mTitle.append( " " );
         ti.mTitle.append( mTrackInfo.mTitle );
      }
      if( mSetAlbum )
      {
         ti.mAlbum = mTrackInfo.mAlbum;
      }
      if( mSetYear )
      {
         ti.mYear = mTrackInfo.mYear;
      }
      if( mSetGenre )
      {
         ti.mGenre = mTrackInfo.mGenre;
      }
      tagsChanged = (ti != oldTags);
      if( mSetFlags )
      {
         if( mTrackInfo.isFlagged( TrackInfo::Favorite ) )
         {
            ti.setFlag( TrackInfo::Favorite, true );
         }
         if( mTrackInfo.isFlagged( TrackInfo::Unwanted ) )
         {
            ti.setFlag( TrackInfo::Unwanted, true );
         }
      }
      if( mUnsetFlags )
      {
         if( mTrackInfo.isFlagged( TrackInfo::Favorite ) )
         {
            ti.setFlag( TrackInfo::Favorite, false );
         }
         if( mTrackInfo.isFlagged( TrackInfo::Unwanted ) )
         {
            ti.setFlag( TrackInfo::Unwanted, false );
         }
         if( mTrackInfo.isFlagged( TrackInfo::ScannedWithPower ) ||
             mTrackInfo.isFlagged( TrackInfo::ScannedWithPeak ) )
         {
            ti.setFlag( TrackInfo::ScannedWithPeak, false );
            ti.mLastScanned = 0;
         }
      }
      if( mSetGroups || mUnsetGroups )
      {
         QStringList groups( mTrackInfo.getGroups() );
         foreach( const QString &group, groups )
         {
            ti.setGroup( group, mSetGroups );
         }
      }
Example #21
0
//Adds dir & its contents to the library
void libraryDialog::addDir2Lib(QDir dir)
{
	dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
	QDirIterator di(dir, QDirIterator::Subdirectories);	

	while(di.hasNext())
	{
		di.next();		
		QString fpath = di.filePath();
		QFileInfo f = di.fileInfo();
		if(isAudioFile(f))//Add this song to the database
		{
			wchar_t wname[250]; //TODO: Dynamic. Need to figure out wchar length from QStr length
			wname[fpath.toWCharArray(wname)] = 0;
			TagLib::FileName fname(wname);
			//We'll store tag information in these:
			QMap<QString, QString> stmap;
			QMap<QString, int> itmap;
			
			TagLib::File* file = NULL;
			//MP3 Means we can check for additional info in ID3v2 tags
			if(f.suffix() == "mp3")
			{				
				TagLib::MPEG::File* fr = new TagLib::MPEG::File(fname, true, TagLib::AudioProperties::ReadStyle::Fast);				
				if(fr->ID3v2Tag())
				{					
					//Somehow this means album artist / band. http://www.id3.org/id3v2.4.0-frames
					TagLib::ID3v2::FrameList l = fr->ID3v2Tag()->frameList("TPE2");
					if(!l.isEmpty())
						stmap["albumartist"] = l.front()->toString().toCString();
				}
				file = dynamic_cast<TagLib::File*>(fr);
			}
			if(file == NULL)
			{
				qDebug() << "ERR: " + fpath;
				continue; //TODO: Error out here
			}
			//Try to get audio properties
			TagLib::AudioProperties* ap = file->audioProperties();			
			
			TagLib::Tag* genTag = file->tag();			
			stmap["name"] = genTag->title().toCString();
			stmap["genre"] = genTag->genre().toCString();
			itmap["year"] = genTag->year();
			itmap["tracknum"] = genTag->track();
			stmap["album"] = genTag->album().toCString();						
			stmap["artist"] = genTag->artist().toCString();			
			if(ap != NULL)
				itmap["length"] = ap->length();
			stmap["path"] = fpath;	
			//Add collected info to db
			DBItem s;
			s.strVals = stmap;
			s.intVals = itmap;

			myparent->dbi->addSong(s);
			delete file;
		}
		else if(f.isDir())
			ui.curDirLbl->setText(fpath);
		//if(top) //If we're the top level of recursion update prog bar
		//	ui.progressBar->setValue(di./siz * 100);		
		qApp->processEvents();
	}
}
void CollectionScanner::popFromQueue() {
    if (stopped) return;

    if (fileQueue.isEmpty()) {
        complete();
        return;
    }

    QFileInfo fileInfo = fileQueue.first();
    // qDebug() << "Processing " << fileInfo.absoluteFilePath();

    // parse metadata with TagLib
    QString filename = fileInfo.absoluteFilePath();
#ifdef Q_OS_WIN
    const wchar_t * encodedName = reinterpret_cast<const wchar_t*>(filename.utf16());
    TagLib::FileRef fileref(encodedName);
#else
    // const char * encodedName = QFile::encodeName(filename).constData();
    TagLib::FileRef fileref((TagLib::FileName)filename.toUtf8());
#endif

    // if taglib cannot parse the file, drop it
    if (fileref.isNull()) {
        // qDebug() << "Taglib cannot parse" << fileInfo.absoluteFilePath();
        fileQueue.removeAll(fileInfo);

        // add to nontracks table
        QString path = fileInfo.absoluteFilePath();
        path.remove(this->rootDirectory.absolutePath() + "/");
        insertOrUpdateNonTrack(path, QDateTime::currentDateTime().toTime_t());

        QTimer::singleShot(0, this, SLOT(popFromQueue()));
        return;
    }

    // Ok this is an interesting file

    // This object will experience an incredible adventure,
    // facing countless perils and finally reaching its final destination
    FileInfo *file = new FileInfo();
    file->setFileInfo(fileInfo);

    // Copy TagLib::FileRef in our Tags class.
    // TagLib::FileRef keeps files open and we would quickly reach the max open files limit
    Tags *tags = new Tags();
    TagLib::Tag *tag = fileref.tag();
    if (tag) {
        tags->title = Tags::toQString(tag->title());
        tags->artist = Tags::toQString(tag->artist());
        tags->album = Tags::toQString(tag->album());
        tags->track = tag->track();
        tags->year = tag->year();
        TagLib::AudioProperties *audioProperties = fileref.audioProperties();
        if (audioProperties)
            tags->length = audioProperties->length();
    }
    file->setTags(tags);

    // get data from the internet
    giveThisFileAnArtist(file);
}
Example #23
0
QString NTagReaderTaglib::parse(const QString &format, bool *success, bool stopOnFail)
{
	if (format.isEmpty())
		return "";

	*success = true;

	if (!isValid())
		return "NTagReaderTaglib::InvalidFile";

	TagLib::Tag *tag = NTaglib::_tagRef->tag();
	TagLib::AudioProperties *ap = NTaglib::_tagRef->audioProperties();

	int seconds_total = ap->length();

	QString res;
	for (int i = 0; i < format.size(); ++i) {
		if (format.at(i) == '%') {
			++i;
			QChar ch = format.at(i);
			if (ch == 'a') {
				QString str = TStringToQString(tag->artist());
				if (!(*success = !str.isEmpty()))
					str = "<Unknown artist>";
				res += str;
			} else if (ch == 't') {
				QString str = TStringToQString(tag->title());
				if (!(*success = !str.isEmpty()))
					str = "<Unknown title>";
				res += str;
			} else if (ch == 'A') {
				QString str = TStringToQString(tag->album());
				if (!(*success = !str.isEmpty()))
					str = "<Unknown album>";
				res += str;
			} else if (ch == 'c') {
				QString str = TStringToQString(tag->comment());
				if (!(*success = !str.isEmpty()))
					str = "<Empty comment>";
				res += str;
			} else if (ch == 'g') {
				QString str = TStringToQString(tag->genre());
				if (!(*success = !str.isEmpty()))
					str = "<Unknown genre>";
				res += str;
			} else if (ch == 'y') {
				QString str = QString::number(tag->year());
				if (str == "0") {
					str = "<Unknown year>";
					*success = false;
				}
				res += str;
			} else if (ch == 'n') {
				QString str = QString::number(tag->track());
				if (str == "0") {
					str = "<Unknown track number>";
					*success = false;
				}
				res += str;
			} else if (ch == 'b') {
				if (auto *prop = dynamic_cast<TagLib::APE::Properties *>(ap)) {
					res += QString::number(prop->bitsPerSample());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::FLAC::Properties *>(ap)) {
					res += QString::number(prop->sampleWidth());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::MP4::Properties *>(ap)) {
					res += QString::number(prop->bitsPerSample());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::RIFF::AIFF::Properties *>(ap)) {
					res += QString::number(prop->sampleWidth());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::RIFF::WAV::Properties *>(ap)) {
					res += QString::number(prop->sampleWidth());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::TrueAudio::Properties *>(ap)) {
					res += QString::number(prop->bitsPerSample());
				}
				else
				if (auto *prop = dynamic_cast<TagLib::WavPack::Properties *>(ap)) {
					res += QString::number(prop->bitsPerSample());
				}
				else {
					res += "<Unknown bit depth>";
					*success = false;
				}
			} else if (ch == 'd') {
				QString duration;
				if (seconds_total > 0) {
					int seconds = seconds_total % 60;
					int minutes = (seconds_total - seconds) / 60;
					int hours = minutes / 60;
					minutes = minutes % 60;
					if (hours > 0)
						duration.sprintf("%d:%02d:%02d", hours, minutes, seconds);
					else
						duration.sprintf("%d:%02d", minutes, seconds);
				} else {
					duration = "<Unknown duration>";
					*success = false;
				}
				res += duration;
			} else if (ch == 'D') {
				QString duration;
				if (seconds_total == 0) {
					duration = "<Unknown duration>";
					*success = false;
				} else {
					duration = QString::number(seconds_total);
				}
				res += duration;
			} else if (ch == 'B') {
				QString str = QString::number(ap->bitrate());
				if (str == "0") {
					str = "<Unknown bitrate>";
					*success = false;
				}
				res += str;
			} else if (ch == 's') {
				QString str = QString::number(ap->sampleRate() / (float)1000);
				if (str == "0") {
					str = "<Unknown sample rate>";
					*success = false;
				}
				res += str;
			} else if (ch == 'C') {
				QString str = QString::number(ap->channels());
				if (str == "0") {
					str = "<Unknown channels number>";
					*success = false;
				}
				res += str;
			} else if (ch == 'f') {
				res += QFileInfo(NTaglib::_filePath).baseName();
			} else if (ch == 'F') {
				res += QFileInfo(NTaglib::_filePath).fileName();
			} else if (ch == 'p') {
				res += QFileInfo(NTaglib::_filePath).absoluteFilePath();
			} else if (ch == 'e') {
				res += QFileInfo(NTaglib::_filePath).suffix();
			} else if (ch == 'E') {
				res += QFileInfo(NTaglib::_filePath).suffix().toUpper();
			} else if (ch == 'v') {
				res += QCoreApplication::applicationVersion();
			} else {
				res += ch;
			}
		} else if (format.at(i) == '{') {
			++i;
			int matchedAt = format.indexOf('}', i);
			if (matchedAt == -1) {
				res += "<condition error: unmatched '{'>";
				return res;
			}

			QString condition = format.mid(i, matchedAt - i);

			if (condition.indexOf('{') != -1) {
				res += "<condition error: extra '{'>";
				return res;
			}

			QStringList values = condition.split('|');
			if (values.count() < 2) {
				res += "<condition error: missing '|'>";
				return res;
			} else if (values.count() > 2) {
				res += "<condition error: extra '|'>";
				return res;
			}

			bool cond_res;
			QString cond_true = parse(values.at(0), &cond_res, true);
			if (cond_res) {
				res += cond_true;
			} else {
				res += parse(values.at(1), &cond_res);
			}
			i = matchedAt;
		} else {
			res += format.at(i);
		}
		if (!*success && stopOnFail)
			return "";
	}

	return res;
}
Example #24
0
Tags *TagUtils::load(const QString &filename) {
#ifdef Q_OS_WIN
    const wchar_t * encodedName = reinterpret_cast<const wchar_t*>(filename.utf16());
    TagLib::FileStream readOnlyStream(encodedName, true);
#else
    TagLib::FileStream readOnlyStream((TagLib::FileName)filename.toUtf8(), true);
#endif

    TagLib::FileRef fileref(&readOnlyStream);
    if (fileref.isNull()) {
        qDebug() << "Taglib cannot parse" << filename;
        return nullptr;
    }

    Tags *tags = new Tags();
    tags->setFilename(filename);

    TagLib::Tag *tag = fileref.tag();
    if (tag) {
        tags->setTitle(TagUtils::qString(tag->title()));
        tags->setArtistString(TagUtils::qString(tag->artist()));
        tags->setAlbumString(TagUtils::qString(tag->album()));
        tags->setGenre(TagUtils::qString(tag->genre()));
        tags->setTrackNumber(tag->track());
        tags->setYear(tag->year());
        tags->setComment(TagUtils::qString(tag->comment()));
        TagLib::AudioProperties *audioProperties = fileref.audioProperties();
        if (audioProperties)
            tags->setDuration(audioProperties->length());
    }

    /*
    TagLib::PropertyMap map = tag->properties();
    for (TagLib::PropertyMap::ConstIterator i = map.begin(); i != map.end(); ++i) {
        for (TagLib::StringList::ConstIterator j = i->second.begin(); j != i->second.end(); ++j) {
            const QString tagName = TagLibUtils::toQString(i->first);
            qDebug() << "PropertyMap" << tagName << TagLibUtils::toQString(*j);
            if (tagName == QLatin1String("ALBUMARTIST"))
                tags->setAlbumArtist(TagLibUtils::toQString(*j));
            else if (tagName == QLatin1String("DISCNUMBER"))
                tags->setDiskNumber(TagLibUtils::toQString(*j).toInt());
            // else if (tagName == QLatin1String("COMPOSER"))
            // tags->setComposer(toQString(*j));
            else if (tagName == QLatin1String("LYRICS"))
                tags->setLyrics(TagLibUtils::toQString(*j));
            //else if (tagName == QLatin1String("BPM"))
            //    tags->bpm = toQString(*j).toInt();
            // else qDebug() << "Unused tag" << tagName << toQString(*j);
        }
    }
    */

    // Handle file types where TagLibf:::File::tag() returns a "TagUnion"
    TagLib::File *file = fileref.file();

    if (TagLib::MPEG::File *f = dynamic_cast<TagLib::MPEG::File*>(file)) {
        if (TagLib::ID3v2::Tag *t = f->ID3v2Tag()) Id3Utils::load(t, tags);

    } else if (TagLib::TrueAudio::File *f = dynamic_cast<TagLib::TrueAudio::File*>(file)) {
        if (TagLib::ID3v2::Tag *t = f->ID3v2Tag()) Id3Utils::load(t, tags);

    } else if (TagLib::FLAC::File *f = dynamic_cast<TagLib::FLAC::File*>(file)) {
        if (TagLib::Ogg::XiphComment *t = f->xiphComment()) VorbisUtils::load(t, tags);
        else if (TagLib::ID3v2::Tag *t = f->ID3v2Tag()) Id3Utils::load(t, tags);

    } else if (TagLib::APE::File *f = dynamic_cast<TagLib::APE::File*>(file)) {
        if (TagLib::APE::Tag *t = f->APETag()) ApeUtils::load(t, tags);

    } else if (TagLib::MPC::File *f = dynamic_cast<TagLib::MPC::File*>(file)) {
        if (TagLib::APE::Tag *t = f->APETag()) ApeUtils::load(t, tags);

    } else if (TagLib::WavPack::File *f = dynamic_cast<TagLib::WavPack::File*>(file)) {
        if (TagLib::APE::Tag *t = f->APETag()) ApeUtils::load(t, tags);

    } else {

        // Fallback to casting tag() for any other file type
        TagLib::Tag *tag = file->tag();

        if (TagLib::ID3v2::Tag *t = dynamic_cast<TagLib::ID3v2::Tag*>(tag))
            Id3Utils::load(t, tags);

        else if (TagLib::Ogg::XiphComment *t = dynamic_cast<TagLib::Ogg::XiphComment*>(tag))
            VorbisUtils::load(t, tags);

        else if (TagLib::APE::Tag *t = dynamic_cast<TagLib::APE::Tag*>(tag))
            ApeUtils::load(t, tags);

        else if (TagLib::MP4::Tag *t = dynamic_cast<TagLib::MP4::Tag*>(tag))
            Mp4Utils::load(t, tags);

        else if (TagLib::ASF::Tag *t = dynamic_cast<TagLib::ASF::Tag*>(tag))
            AsfUtils::load(t, tags);
    }

    return tags;
}
Example #25
0
bool SoundSource::processTaglibFile(TagLib::File& f) {
    if (s_bDebugMetadata)
        qDebug() << "Parsing" << getFilename();

    if (f.isValid()) {
        TagLib::Tag *tag = f.tag();
        if (tag) {
            QString title = TStringToQString(tag->title());
            setTitle(title);

            QString artist = TStringToQString(tag->artist());
            setArtist(artist);

            QString album = TStringToQString(tag->album());
            setAlbum(album);

            QString comment = TStringToQString(tag->comment());
            setComment(comment);

            QString genre = TStringToQString(tag->genre());
            setGenre(genre);

            int iYear = tag->year();
            QString year = "";
            if (iYear > 0) {
                year = QString("%1").arg(iYear);
                setYear(year);
            }

            int iTrack = tag->track();
            QString trackNumber = "";
            if (iTrack > 0) {
                trackNumber = QString("%1").arg(iTrack);
                setTrackNumber(trackNumber);
            }

            if (s_bDebugMetadata)
                qDebug() << "TagLib" << "title" << title << "artist" << artist << "album" << album << "comment" << comment << "genre" << genre << "year" << year << "trackNumber" << trackNumber;
        }

        TagLib::AudioProperties *properties = f.audioProperties();
        if (properties) {
            int lengthSeconds = properties->length();
            int bitrate = properties->bitrate();
            int sampleRate = properties->sampleRate();
            int channels = properties->channels();

            if (s_bDebugMetadata)
                qDebug() << "TagLib" << "length" << lengthSeconds << "bitrate" << bitrate << "sampleRate" << sampleRate << "channels" << channels;

            setDuration(lengthSeconds);
            setBitrate(bitrate);
            setSampleRate(sampleRate);
            setChannels(channels);
        }

        // If we didn't get any audio properties, this was a failure.
        return (properties!=NULL);
    }
    return false;
}