Ejemplo n.º 1
1
Vec2f Slider::getSliderTrackSize(void) const
{
    if(getOrientation() == VERTICAL_ORIENTATION)
    {
        return Vec2f(0, getTrackLength());
    }
    else
    {
        return Vec2f(getTrackLength(), 0);
    }
}
Ejemplo n.º 2
0
void VectorTrack::getSpotOnTrack(double pos, double vertical, double& x, double& y, double &rot)
{
	if (pos <= 0 || pos >= 1)
	{
		return;
	}

	unsigned int i;

	//acquire the distance actually along the track
	double soFar = pos*getTrackLength();
	
	for (i = 0; i < pointList.size(); i++)
	{
		if (soFar <= getSpecificTrackLength(0, i))
		{
			//now recompute soFar to be where between the two points on a [0,1] scale
			soFar = (soFar - getSpecificTrackLength(0, i-1))/getSpecificTrackLength(i-1, i);
			break;
		}
	}
	
	ParametricPoint a = pointList.at(i-1);
        ParametricPoint b = pointList.at(i);

	x = (1 - soFar)*(a.x) + soFar*(b.x);
	y = (1 - soFar)*(a.y) + soFar*(b.y);
	
	rot = (180.0/M_PI)*atan2(b.y - a.y, b.x - a.x);
	
	x += vertical*cos((M_PI/180.0)*(rot + 90));
	y += vertical*sin((M_PI/180.0)*(rot + 90));
}
Ejemplo n.º 3
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata* MetaIOFLACVorbis::read(QString filename)
{
    TagLib::FLAC::File *flacfile = OpenFile(filename);
    
    if (!flacfile)
        return NULL;
    
    TagLib::Ogg::XiphComment *tag = flacfile->xiphComment();
    
    if (!tag)
    {
        delete flacfile;
        return NULL;
    }
    
    Metadata *metadata = new Metadata(filename);
    
    ReadGenericMetadata(tag, metadata);
    
    bool compilation = false;

    if (tag->contains("COMPILATION_ARTIST"))
    {
        QString compilation_artist = TStringToQString(
            tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed();
        if (compilation_artist != metadata->Artist())
        {
            metadata->setCompilationArtist(compilation_artist);
            compilation = true;
        }
    }
    
    if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID"))
    {
        QString musicbrainzcode = TStringToQString(
        tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed();
        if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)
            compilation = true;
    }

    metadata->setCompilation(compilation);

    if (metadata->Length() <= 0)
    {
        TagLib::FileRef *fileref = new TagLib::FileRef(flacfile);
        metadata->setLength(getTrackLength(fileref));
        // FileRef takes ownership of flacfile, and is responsible for it's
        // deletion. Messy.
        delete fileref;
    }
    else
        delete flacfile;
    
    return metadata;
}
Ejemplo n.º 4
0
void VectorTrack::computeCameraCoordinates(double pos, double& camX, double& camY, double& camZ, double& lookX, double& lookY, double& lookZ)
{
	if (pos <= 0 || pos >= 1)
	{
		return;
	}

	unsigned int i;

	//acquire the distance actually along the track
	double soFar = pos*getTrackLength();
	
	for (i = 0; i < pointList.size(); i++)
	{
		if (soFar <= getSpecificTrackLength(0, i))
		{
			//now recompute soFar to be where between the two points on a [0,1] scale
			soFar = (soFar - getSpecificTrackLength(0, i-1))/getSpecificTrackLength(i-1, i);
			break;
		}
	}
	
	ParametricPoint a = pointList.at(i-1);
        ParametricPoint b = pointList.at(i);

	double x = (1 - soFar)*(a.x) + soFar*(b.x);
	double y = (1 - soFar)*(a.y) + soFar*(b.y);
	
	double aAngle = a.normalDirection;
	double bAngle = b.normalDirection;
	
	if (fabs(bAngle - aAngle) > 180.0)
	{
		if (bAngle > aAngle)
		{
			bAngle -= 360.0;
		}
		else
		{
			aAngle -= 360.0;
		}
	}

	//compute the interpolated direction between a's and b's direction
	double midAngle = (1 - soFar)*(aAngle) + soFar*(bAngle);
	
	camX = x + 6*sin((M_PI/180.0)*(midAngle + 180));
	camY = y + 6*cos((M_PI/180.0)*(midAngle + 180));
	camZ = 5.0;

	lookX = x - camX;
	lookY = y - camY;
	lookZ = -3.0;
}
Ejemplo n.º 5
0
/*!
* \copydoc MetaIO::read()
*/
Metadata* MetaIOOggVorbis::read(const QString &filename)
{
    TagLib::Ogg::Vorbis::File *oggfile = OpenFile(filename);

    if (!oggfile)
        return NULL;

    TagLib::Ogg::XiphComment *tag = oggfile->tag();

    if (!tag)
    {
        delete oggfile;
        return NULL;
    }

    Metadata *metadata = new Metadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    if (tag->contains("COMPILATION_ARTIST"))
    {
        QString compilation_artist = TStringToQString(
            tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed();
        if (compilation_artist != metadata->Artist())
        {
            metadata->setCompilationArtist(compilation_artist);
            compilation = true;
        }
    }

    if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID"))
    {
        QString musicbrainzcode = TStringToQString(
        tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed();
        if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)
            compilation = true;
    }

    metadata->setCompilation(compilation);

    if (metadata->Length() <= 0)
        metadata->setLength(getTrackLength(oggfile));
    else
        delete oggfile;

    return metadata;
}
Ejemplo n.º 6
0
MusicMetadata* MetaIO::readFromFilename(const QString &filename, bool blnLength)
{
    QString artist, album, title, genre;
    int tracknum = 0, length = 0;

    readFromFilename(filename, artist, album, title, genre, tracknum);

    if (blnLength)
        length = getTrackLength(filename);

    MusicMetadata *retdata = new MusicMetadata(filename, artist, "", album,
                                               title, genre, 0, tracknum, length);

    return retdata;
}
Ejemplo n.º 7
0
/*!
* \copydoc MetaIO::read()
*/
Metadata* MetaIOAVFComment::read(QString filename)
{
    QString artist, compilation_artist, album, title, genre;
    int year = 0, tracknum = 0, length = 0;

    AVFormatContext* p_context = NULL;
    AVFormatParameters* p_params = NULL;
    AVInputFormat* p_inputformat = NULL;

    QByteArray local8bit = filename.toLocal8Bit();
    if ((av_open_input_file(&p_context, local8bit.constData(),
                           p_inputformat, 0, p_params) < 0))
    {
        return NULL;
    }

    if (av_find_stream_info(p_context) < 0)
        return NULL;


    title += (char *)p_context->title;
    if (title.isEmpty())
    {
        readFromFilename(filename, artist, album, title, genre, tracknum);
    }
    else
    {
        artist += (char *)p_context->author;
        // compilation_artist???
        album += (char *)p_context->album;
        genre += (char *)p_context->genre;
        year = p_context->year;
        tracknum = p_context->track;
    }

    length = getTrackLength(p_context);

    Metadata *retdata = new Metadata(filename, artist, compilation_artist, album,
                                     title, genre, year, tracknum, length);

    retdata->determineIfCompilation();

    av_close_input_file(p_context);

    return retdata;
}
Ejemplo n.º 8
0
/**
 * Begin playback of a specifc audio track, possibly looped.
 */
int DM_CDAudio_Play(int track, int looped)
{
    int len;

    if(!cdInited)
        return false;

    // Get the length of the track.
    cdTrackLength = len = getTrackLength(track);
    if(!len)
        return false; // Hmm?!

    // Play it!
    if(!sendMCICmd(0, 0, "play " DEVICEID " from %i to %i", track,
                   MCI_MAKE_TMSF(track, 0, len, 0)))
        return false;

    // Success!
    cdLooping = (looped? true:false);
    cdStartTime = Timer_Seconds();
    return cdCurrentTrack = track;
}
Ejemplo n.º 9
0
/*!
 * \brief Find the length of the track (in seconds)
 *
 * \param filename The filename for which we want to find the length.
 * \returns An integer (signed!) to represent the length in seconds.
 */
int MetaIOMP4::getTrackLength(const QString &filename)
{
    AVFormatContext* p_context = NULL;
    AVInputFormat* p_inputformat = NULL;

    // Open the specified file and populate the metadata info
    QByteArray local8bit = filename.toLocal8Bit();
    if ((avformat_open_input(&p_context, local8bit.constData(),
                             p_inputformat, NULL) < 0))
    {
        return 0;
    }

    if (avformat_find_stream_info(p_context, NULL) < 0)
        return 0;

    int rv = getTrackLength(p_context);

    avformat_close_input(&p_context);

    return rv;
}
Ejemplo n.º 10
0
/*!
 * \brief Find the length of the track (in seconds)
 *
 * \param filename The filename for which we want to find the length.
 * \returns An integer (signed!) to represent the length in seconds.
 */
int MetaIOAVFComment::getTrackLength(QString filename)
{
    AVFormatContext* p_context = NULL;
    AVFormatParameters* p_params = NULL;
    AVInputFormat* p_inputformat = NULL;

    // Open the specified file and populate the metadata info
    QByteArray local8bit = filename.toLocal8Bit();
    if ((av_open_input_file(&p_context, local8bit.constData(),
                           p_inputformat, 0, p_params) < 0))
    {
        return 0;
    }

    if (av_find_stream_info(p_context) < 0)
        return 0;

    int rv = getTrackLength(p_context);

    av_close_input_file(p_context);

    return rv;
}
Ejemplo n.º 11
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata *MetaIOID3::read(QString filename)
{
    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return NULL;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return NULL;
    }

    // if there is no ID3v2 tag, try to read the ID3v1 tag and copy it to the ID3v2 tag structure
    if (tag->isEmpty())
    {
        TagLib::ID3v1::Tag *tag_v1 = mpegfile->ID3v1Tag();

        if (!tag_v1)
        {
            delete mpegfile;
            return NULL;
        }

        if (!tag_v1->isEmpty())
        {
            tag->setTitle(tag_v1->title());
            tag->setArtist(tag_v1->artist());
            tag->setAlbum(tag_v1->album());
            tag->setTrack(tag_v1->track());
            tag->setYear(tag_v1->year());
            tag->setGenre(tag_v1->genre());
        }
    }

    Metadata *metadata = new Metadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    // Compilation Artist (TPE4 Remix) or fallback to (TPE2 Band)
    // N.B. The existance of a either frame is NOT an indication that this
    // is a compilation, but if it is then one of them will probably hold
    // the compilation artist.
    TextIdentificationFrame *tpeframe = NULL;
    TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
    if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty())
        tpelist = tag->frameListMap()["TPE2"];
    if (!tpelist.isEmpty())
        tpeframe = (TextIdentificationFrame *)tpelist.front();

    if (tpeframe && !tpeframe->toString().isEmpty())
    {
        QString compilation_artist = TStringToQString(tpeframe->toString())
                                                                    .trimmed();
        metadata->setCompilationArtist(compilation_artist);
    }

    // MythTV rating and playcount, stored in POPM frame
    PopularimeterFrame *popm = findPOPM(tag, email);

    if (!popm)
    {
        if (!tag->frameListMap()["POPM"].isEmpty())
            popm = dynamic_cast<PopularimeterFrame *>
                                        (tag->frameListMap()["POPM"].front());
    }

    if (popm)
    {
        int rating = popm->rating();
        rating = static_cast<int>(((static_cast<float>(rating)/255.0)
                                                                * 10.0) + 0.5);
        metadata->setRating(rating);
        metadata->setPlaycount(popm->counter());
    }

    // Look for MusicBrainz Album+Artist ID in TXXX Frame
    UserTextIdentificationFrame *musicbrainz = find(tag,
                                            "MusicBrainz Album Artist Id");

    if (musicbrainz)
    {
        // If the MusicBrainz ID is the special "Various Artists" ID
        // then compilation is TRUE
        if (!compilation && !musicbrainz->fieldList().isEmpty())
            compilation = (MYTH_MUSICBRAINZ_ALBUMARTIST_UUID
            == TStringToQString(musicbrainz->fieldList().front()));
    }

    // TLEN - Ignored intentionally, some encoders write bad values
    // e.g. Lame under certain circumstances will always write a length of
    // 27 hours

    metadata->setCompilation(compilation);

    TagLib::FileRef *fileref = new TagLib::FileRef(mpegfile);
    metadata->setLength(getTrackLength(fileref));
    // FileRef takes ownership of mpegfile, and is responsible for it's
    // deletion. Messy.
    delete fileref;

    return metadata;
}
Ejemplo n.º 12
0
Int32 Slider::getTrackMax(void) const
{
    return getTrackMin() + getTrackLength();
}
Ejemplo n.º 13
0
void Slider::updateLayout(void)
{

    UInt16 MajorAxis, MinorAxis;
    if(getOrientation() == VERTICAL_ORIENTATION)
    {
        MajorAxis = 1;
    }
    else
    {
        MajorAxis = 0;
    }
    MinorAxis = (MajorAxis+1)%2;

    updateSliderTrack();

    //Update the Track
    if(getDrawTrack() && getTrackDrawObject() != NULL)
    {
        Pnt2f BorderTopLeft, BorderBottomRight;
        getInsideInsetsBounds(BorderTopLeft, BorderBottomRight);

        Vec2f Size(getTrackDrawObject()->getPreferredSize());
        Pnt2f AlignedPosition;
        Size[MajorAxis] = getTrackLength();

        if(getOrientation() == VERTICAL_ORIENTATION)
        {
            AlignedPosition = calculateAlignment(BorderTopLeft, (BorderBottomRight-BorderTopLeft), Size, 0.5, getAlignment());
        }
        else
        {
            AlignedPosition = calculateAlignment(BorderTopLeft, (BorderBottomRight-BorderTopLeft), Size, getAlignment(), 0.5);
        }

        getTrackDrawObject()->setPosition(AlignedPosition);
        getTrackDrawObject()->setSize(Size);
    }

    //Update the MinorTickMarks
    if(getDrawMinorTicks() && getRangeModel() != NULL)
    {
        Pnt2f MinorTickTopLeft, MinorTickBottomRight;
        getDrawObjectBounds(*editMFMinorTickDrawObjects(), MinorTickTopLeft, MinorTickBottomRight);

        Vec2f Alignment;

        Real32 MaxLength(0.0);
        for(UInt32 i(0) ; i<getMFMinorTickDrawObjects()->size() ; ++i)
        {
            Pnt2f DrawObjectTopLeft, DrawObjectBottomRight;
            getMinorTickDrawObjects(i)->getBounds(DrawObjectTopLeft, DrawObjectBottomRight);
            MaxLength = osgMax(MaxLength, DrawObjectBottomRight.x()-DrawObjectTopLeft.x());
        }
        editMFMinorTickPositions()->clear();

        for(UInt32 i(0) ; i< osgAbs<Int32>(getMaximum() - getMinimum())/getMinorTickSpacing() ; ++i)
        {
            if( (i * getMinorTickSpacing())%getMajorTickSpacing() != 0 )
            {
                Alignment[MajorAxis] = static_cast<Real32>(i * getMinorTickSpacing())/static_cast<Real32>(getMaximum() - getMinimum());
                editMFMinorTickPositions()->push_back(
                                                  calculateSliderAlignment(getSliderTrackTopLeft(), getSliderTrackSize(), (MinorTickBottomRight - MinorTickTopLeft), Alignment.y(), Alignment.x()));
                if(getTicksOnRightBottom())
                {
                    editMFMinorTickPositions()->back()[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] + getTrackDrawObject()->getSize()[MinorAxis] + getTrackToTickOffset();
                }
                else
                {
                    editMFMinorTickPositions()->back()[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] - getTrackToTickOffset() - MaxLength;
                }
            }
        }

    }

    //Update the MajorTickMarks
    if(getDrawMajorTicks() && getRangeModel() != NULL)
    {
        Pnt2f MajorTickTopLeft, MajorTickBottomRight;
        getDrawObjectBounds(*editMFMajorTickDrawObjects(), MajorTickTopLeft, MajorTickBottomRight);

        Vec2f Alignment;

        Real32 MaxLength(0.0);
        for(UInt32 i(0) ; i<getMFMajorTickDrawObjects()->size() ; ++i)
        {
            Pnt2f DrawObjectTopLeft, DrawObjectBottomRight;
            getMajorTickDrawObjects(i)->getBounds(DrawObjectTopLeft, DrawObjectBottomRight);
            MaxLength = osgMax(MaxLength, DrawObjectBottomRight.x()-DrawObjectTopLeft.x());
        }
        editMFMajorTickPositions()->clear();

        for(UInt32 i(0) ; i<= osgAbs<Int32>(getMaximum() - getMinimum())/getMajorTickSpacing() ; ++i)
        {
            Alignment[MajorAxis] = static_cast<Real32>(i * getMajorTickSpacing())/static_cast<Real32>(getMaximum() - getMinimum());
            editMFMajorTickPositions()->push_back(
                                              calculateSliderAlignment(getSliderTrackTopLeft(), getSliderTrackSize(), (MajorTickBottomRight - MajorTickTopLeft), Alignment.y(), Alignment.x()));
            if(getTicksOnRightBottom())
            {
                editMFMajorTickPositions()->back()[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] + getTrackDrawObject()->getSize()[MinorAxis] + getTrackToTickOffset();
            }
            else
            {
                editMFMajorTickPositions()->back()[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] - getTrackToTickOffset() - MaxLength;
            }
        }

    }

    //Update the Labels
    if(getDrawLabels() && getRangeModel() != NULL)
    {
        Vec2f Alignment;
        Pnt2f Pos;
        FieldContainerMap::const_iterator Itor;
        for(Itor = getLabelMap().begin() ; Itor != getLabelMap().end() ; ++Itor)
        {
            Alignment[MajorAxis] = static_cast<Real32>((*Itor).first - getMinimum())/static_cast<Real32>(getMaximum() - getMinimum());
            Pos = calculateSliderAlignment(getSliderTrackTopLeft(), getSliderTrackSize(), dynamic_pointer_cast<Component>((*Itor).second)->getPreferredSize(), Alignment.y(), Alignment.x());
            if(getTicksOnRightBottom())
            {
                Pos[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] + getTrackDrawObject()->getSize()[MinorAxis] + getTrackToLabelOffset();
            }
            else
            {
                Pos[MinorAxis] = getTrackDrawObject()->getPosition()[MinorAxis] - getTrackToLabelOffset() - dynamic_pointer_cast<Component>((*Itor).second)->getPreferredSize()[MinorAxis];
            }

            dynamic_pointer_cast<Component>((*Itor).second)->setPosition(Pos);
            dynamic_pointer_cast<Component>((*Itor).second)->setSize(dynamic_pointer_cast<Component>((*Itor).second)->getPreferredSize());
        }
    }
}
Ejemplo n.º 14
0
void Track::writeData( QByteArray& data) const {
    QBuffer buffer( data);
    buffer.open(IO_WriteOnly);
    QDataStream stream( &buffer);
    stream.setByteOrder( QDataStream::LittleEndian);

    /** Write the track header **/
    stream << (Q_UINT32) 0x7469686D;        // 0x00 mhit
    stream << (Q_UINT32) 0xf4;              // 0x04 headerlen
    stream << (Q_UINT32) 0x0;               // 0x08 length - set later
    stream << (Q_UINT32) 0x0;               // 0x0C number of mhods
    stream << (Q_UINT32) getID();           // 0x10
    stream << (Q_UINT32) 1;                 // 0x14
    //stream << (Q_UINT32) 0;                 // 0x18
    stream << (Q_UINT32) 0x4d503320;        // ipod shiffle wants a "MP3 " here
    stream << vbr;                          // 0x1C
    stream << type;                         // 0x1D
    stream << compilation;                  // 0x1E
    stream << rating;                       // 0x1F
    stream << (Q_UINT32) getLastModified()+ MAC_EPOCH_DELTA; // 0x20
    stream << (Q_UINT32) getFileSize();     // 0x24
    stream << (Q_UINT32) getTrackLength();  // 0x28
    stream << (Q_UINT32) getTrackNumber();  // 0x2C
    stream << (Q_UINT32) getTrackCount();   // 0x30
    stream << (Q_UINT32) getYear();         // 0x34
    stream << (Q_UINT32) getBitrate();      // 0x38
    stream << (Q_UINT32) getSamplerate();   // 0x3C
    stream << (Q_UINT32) getVolumeAdjust(); // 0x40
    stream << (Q_UINT32) 0;                 // 0x44 empty space
    //stream << (Q_UINT32) getTrackLength();  // 0x48 empty space
    stream << (Q_UINT32) 0;  // 0x48 empty space
    stream << (Q_UINT32) 0;                 // 0x4C empty space
    stream << (Q_UINT32) getPlayCount();    // 0x50
    stream << (Q_UINT32) getPlayCount();    // 0x54
    stream << (Q_UINT32) getLastPlayed();   // 0x58
    stream << (Q_UINT32) getCdNumber();     // 0x5C
    stream << (Q_UINT32) getCdCount();      // 0x60
    stream << (Q_UINT32) 0;                 // 0x64 empty space //userid from apple store
    stream << (Q_UINT32) date_added;        // 0x68
    stream << (Q_UINT32) 0;                 // boockmarktime
    stream << (Q_UINT64) dbid;              // unique bit (64 bit)
    stream << (Q_UINT8) 0;                 // checked in iTZnes
    stream << (Q_UINT8) 0;                 // application rating
    stream << (Q_UINT16) 0;                 // BPM
    stream << (Q_UINT16) 0;                 // artworkcount
    stream << (Q_UINT16) 0xffff;            // unkown
    stream << (Q_UINT32) 0;                 // artwork size
    stream << (Q_UINT32) 0;                 // unkown
    stream << (float) -getSamplerate();      // samplerate as floating point "-"?!?
    stream << (Q_UINT32) 0;                 // date/time added
    stream << (Q_UINT32) file_format_code;  // unkown, but 0x0000000c for MP3 ?
    stream << (Q_UINT32) 0;                 // unkown
    stream << (Q_UINT32) 0;                 // unkown
    stream << (Q_UINT32) 0;                 // unkown
    stream << (Q_UINT32) 0;                 // unkown
    stream << (Q_UINT32) 0x02;              // unknown
    stream << (Q_UINT64) dbid; // same unique id as above
    for( int i= 0; i< 17; i++)
        stream << (Q_UINT32) 0;
    
    /** Write Track contents **/
    Q_UINT32 num_mhods = 0;
    for( PropertyMap::const_iterator element= properties.begin(); element!= properties.end(); ++element) {
        if( (*element).isEmpty())
            continue;

        const char *data= (const char *)(*element).ucs2();
        if( data == NULL)
            continue;

        int datalen= 2* (*element).length();

        stream << (Q_UINT32) 0x646F686D;    // mhod
        stream << (Q_UINT32) 0x18;    // headerlen
        stream << (Q_UINT32) 40+ datalen;
        stream << (Q_UINT32) element.key();
        stream << (Q_UINT32) 0;
        stream << (Q_UINT32) 0;
        stream << (Q_UINT32) 1;    // dummy - would refer to the trackID if used in playlist
        stream << (Q_UINT32) datalen;
        stream << (Q_UINT32) 0;
        stream << (Q_UINT32) 0;
        stream.writeRawBytes( data, datalen);
        num_mhods++;
    }
    buffer.at( 8);
    stream << (Q_UINT32)data.size();	// set content length
    stream << (Q_UINT32)num_mhods;	// set real mhod count
    buffer.close();
}
Ejemplo n.º 15
0
/*!
 * \copydoc MetaIO::read()
 */
MusicMetadata *MetaIOID3::read(const QString &filename)
{
    if (!OpenFile(filename))
        return nullptr;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag(true); // Create tag if none are found

    // if there is no ID3v2 tag, try to read the ID3v1 tag and copy it to
    // the ID3v2 tag structure
    if (tag->isEmpty())
    {
        TagLib::ID3v1::Tag *tag_v1 = GetID3v1Tag();

        if (!tag_v1)
            return nullptr;

        if (!tag_v1->isEmpty())
        {
            tag->setTitle(tag_v1->title());
            tag->setArtist(tag_v1->artist());
            tag->setAlbum(tag_v1->album());
            tag->setTrack(tag_v1->track());
            tag->setYear(tag_v1->year());
            tag->setGenre(tag_v1->genre());
        }
    }

    MusicMetadata *metadata = new MusicMetadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    // Compilation Artist (TPE4 Remix) or fallback to (TPE2 Band)
    // N.B. The existance of a either frame is NOT an indication that this
    // is a compilation, but if it is then one of them will probably hold
    // the compilation artist.
    TextIdentificationFrame *tpeframe = nullptr;
    TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
    if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty())
        tpelist = tag->frameListMap()["TPE2"];
    if (!tpelist.isEmpty())
        tpeframe = (TextIdentificationFrame *)tpelist.front();

    if (tpeframe && !tpeframe->toString().isEmpty())
    {
        QString compilation_artist = TStringToQString(tpeframe->toString())
                                                                    .trimmed();
        metadata->setCompilationArtist(compilation_artist);
    }

    // Rating and playcount, stored in POPM frame
    PopularimeterFrame *popm = findPOPM(tag, ""); // Global (all apps) tag

    // If no 'global' tag exists, look for the MythTV specific one
    if (!popm)
    {
        popm = findPOPM(tag, email);
    }

    // Fallback to using any POPM tag we can find
    if (!popm)
    {
        if (!tag->frameListMap()["POPM"].isEmpty())
            popm = dynamic_cast<PopularimeterFrame *>
                                        (tag->frameListMap()["POPM"].front());
    }

    if (popm)
    {
        int rating = popm->rating();
        rating = lroundf(static_cast<float>(rating) / 255.0f * 10.0f);
        metadata->setRating(rating);
        metadata->setPlaycount(popm->counter());
    }

    // Look for MusicBrainz Album+Artist ID in TXXX Frame
    UserTextIdentificationFrame *musicbrainz = find(tag,
                                            "MusicBrainz Album Artist Id");

    if (musicbrainz)
    {
        // If the MusicBrainz ID is the special "Various Artists" ID
        // then compilation is TRUE
        if (!compilation && !musicbrainz->fieldList().isEmpty())
        {
            TagLib::StringList l = musicbrainz->fieldList();
            for (TagLib::StringList::ConstIterator it = l.begin(); it != l.end(); it++)
            {
                QString ID = TStringToQString((*it));

                if (ID == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID)
                {
                    compilation = true;
                    break;
                }
            }
        }
    }

    // TLEN - Ignored intentionally, some encoders write bad values
    // e.g. Lame under certain circumstances will always write a length of
    // 27 hours

    // Length
    if (!tag->frameListMap()["TLEN"].isEmpty())
    {
        int length = tag->frameListMap()["TLEN"].front()->toString().toInt();
        LOG(VB_FILE, LOG_DEBUG,
            QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length));
    }

    metadata->setCompilation(compilation);

    metadata->setLength(getTrackLength(m_file));

    // The number of tracks on the album, if supplied
    if (!tag->frameListMap()["TRCK"].isEmpty())
    {
        QString trackFrame = TStringToQString(
                                tag->frameListMap()["TRCK"].front()->toString())
                                    .trimmed();
        int trackCount = trackFrame.section('/', -1).toInt();
        if (trackCount > 0)
            metadata->setTrackCount(trackCount);
    }

    LOG(VB_FILE, LOG_DEBUG,
            QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length()));

    // Look for MythTVLastPlayed in TXXX Frame
    UserTextIdentificationFrame *lastplayed = find(tag, "MythTVLastPlayed");
    if (lastplayed)
    {
        QString lastPlayStr = TStringToQString(lastplayed->toString());
        metadata->setLastPlay(QDateTime::fromString(lastPlayStr, Qt::ISODate));
    }

    // Part of a set
    if (!tag->frameListMap()["TPOS"].isEmpty())
    {
        QString pos = TStringToQString(
                        tag->frameListMap()["TPOS"].front()->toString()).trimmed();

        int discNumber = pos.section('/', 0, 0).toInt();
        int discCount  = pos.section('/', -1).toInt();

        if (discNumber > 0)
            metadata->setDiscNumber(discNumber);
        if (discCount > 0)
            metadata->setDiscCount(discCount);
    }

    return metadata;
}
Ejemplo n.º 16
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata *MetaIOID3::read(const QString &filename)
{
    if (!OpenFile(filename))
        return NULL;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag(true); // Create tag if none are found

    // if there is no ID3v2 tag, try to read the ID3v1 tag and copy it to
    // the ID3v2 tag structure
    if (tag->isEmpty())
    {
        TagLib::ID3v1::Tag *tag_v1 = GetID3v1Tag();

        if (!tag_v1)
            return NULL;

        if (!tag_v1->isEmpty())
        {
            tag->setTitle(tag_v1->title());
            tag->setArtist(tag_v1->artist());
            tag->setAlbum(tag_v1->album());
            tag->setTrack(tag_v1->track());
            tag->setYear(tag_v1->year());
            tag->setGenre(tag_v1->genre());
        }
    }

    Metadata *metadata = new Metadata(filename);

    ReadGenericMetadata(tag, metadata);

    bool compilation = false;

    // Compilation Artist (TPE4 Remix) or fallback to (TPE2 Band)
    // N.B. The existance of a either frame is NOT an indication that this
    // is a compilation, but if it is then one of them will probably hold
    // the compilation artist.
    TextIdentificationFrame *tpeframe = NULL;
    TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
    if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty())
        tpelist = tag->frameListMap()["TPE2"];
    if (!tpelist.isEmpty())
        tpeframe = (TextIdentificationFrame *)tpelist.front();

    if (tpeframe && !tpeframe->toString().isEmpty())
    {
        QString compilation_artist = TStringToQString(tpeframe->toString())
                                                                    .trimmed();
        metadata->setCompilationArtist(compilation_artist);
    }

    // MythTV rating and playcount, stored in POPM frame
    PopularimeterFrame *popm = findPOPM(tag, email);

    if (!popm)
    {
        if (!tag->frameListMap()["POPM"].isEmpty())
            popm = dynamic_cast<PopularimeterFrame *>
                                        (tag->frameListMap()["POPM"].front());
    }

    if (popm)
    {
        int rating = popm->rating();
        rating = static_cast<int>(((static_cast<float>(rating)/255.0)
                                                                * 10.0) + 0.5);
        metadata->setRating(rating);
        metadata->setPlaycount(popm->counter());
    }

    // Look for MusicBrainz Album+Artist ID in TXXX Frame
    UserTextIdentificationFrame *musicbrainz = find(tag,
                                            "MusicBrainz Album Artist Id");

    if (musicbrainz)
    {
        // If the MusicBrainz ID is the special "Various Artists" ID
        // then compilation is TRUE
        if (!compilation && !musicbrainz->fieldList().isEmpty())
            compilation = (MYTH_MUSICBRAINZ_ALBUMARTIST_UUID
            == TStringToQString(musicbrainz->fieldList().front()));
    }

    // TLEN - Ignored intentionally, some encoders write bad values
    // e.g. Lame under certain circumstances will always write a length of
    // 27 hours

    // Length
    if (!tag->frameListMap()["TLEN"].isEmpty())
    {
        int length = tag->frameListMap()["TLEN"].front()->toString().toInt();
        LOG(VB_FILE, LOG_DEBUG,
            QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length));
    }

    metadata->setCompilation(compilation);

    metadata->setLength(getTrackLength(m_file));

    // The number of tracks on the album, if supplied
    if (!tag->frameListMap()["TRCK"].isEmpty())
    {
        QString trackFrame = TStringToQString(
                                tag->frameListMap()["TRCK"].front()->toString())
                                    .trimmed();
        int trackCount = trackFrame.section('/', -1).toInt();
        if (trackCount > 0)
            metadata->setTrackCount(trackCount);
    }

    LOG(VB_FILE, LOG_DEBUG,
            QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length()));

    return metadata;
}
Ejemplo n.º 17
0
/*!
 * \copydoc MetaIO::read()
 */
Metadata* MetaIOMP4::read(const QString &filename)
{
    QString title, artist, album, genre;
    int year = 0, tracknum = 0, length = 0;
    bool compilation = false;

    AVFormatContext* p_context = NULL;
    AVInputFormat* p_inputformat = NULL;

    QByteArray local8bit = filename.toLocal8Bit();
    if ((avformat_open_input(&p_context, local8bit.constData(),
                             p_inputformat, NULL) < 0))
    {
        return NULL;
    }

    if (avformat_find_stream_info(p_context, NULL) < 0)
        return NULL;

#if 0
    //### Debugging, enable to dump a list of all field names/values found

    AVDictionaryEntry *tag = av_dict_get(p_context->metadata, "\0", NULL,
                                         AV_METADATA_IGNORE_SUFFIX);
    while (tag != NULL)
    {
        LOG(VB_GENERAL, LOG_DEBUG, QString("Tag: %1 Value: %2")
                .arg(tag->key) .arg(QString::fromUtf8(tag->value)));
        tag = av_dict_get(p_context->metadata, "\0", tag,
                          AV_METADATA_IGNORE_SUFFIX);
    }
    //####
#endif

    title = getFieldValue(p_context, "title");
    if (title.isEmpty())
    {
        readFromFilename(filename, artist, album, title, genre, tracknum);
    }
    else
    {
        title = getFieldValue(p_context, "title");
        artist = getFieldValue(p_context, "author");
        // Author is the correct fieldname, but
        // we've been saving to artist for years
        if (artist.isEmpty())
            artist = getFieldValue(p_context, "artist");
        album = getFieldValue(p_context, "album");
        year = getFieldValue(p_context, "year").toInt();
        genre = getFieldValue(p_context, "genre");
        tracknum = getFieldValue(p_context, "track").toInt();
        compilation = getFieldValue(p_context, "").toInt();
        length = getTrackLength(p_context);
    }

    metadataSanityCheck(&artist, &album, &title, &genre);

    Metadata *retdata = new Metadata(filename,
                                     artist,
                                     compilation ? artist : "",
                                     album,
                                     title,
                                     genre,
                                     year,
                                     tracknum,
                                     length);

    retdata->setCompilation(compilation);

    avformat_close_input(&p_context);

    return retdata;
}