int main(int argc, char *argv[])
{
    FMOD::System    *system;
    FMOD::Sound     *sound;
    FMOD::Channel   *channel = 0;
    FMOD_RESULT      result;
    int              key;
    unsigned int     version;

    memset(gCurrentTrackArtist, 0, 256);
    memset(gCurrentTrackTitle, 0, 256);
    strcpy(gOutputFileName, "output.mp3");   /* Start off like this then rename if a title tag comes along */

    printf("======================================================================\n");
    printf("RipNetStream Example.  Copyright (c) Firelight Technologies 2004-2014.\n");
    printf("======================================================================\n\n");

    if (argc < 2)
    {
        printf("Usage:   ripnetstream <url>\n");
        return -1;
    }

    /*
        Create a System object and initialize.
    */
    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->getVersion(&version);
    ERRCHECK(result);

    if (version < FMOD_VERSION)
    {
        printf("Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", version, FMOD_VERSION);
        return 0;
    }

    result = system->init(100, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    result = system->setStreamBufferSize(gFileBufferSize, FMOD_TIMEUNIT_RAWBYTES);
    ERRCHECK(result);

    result = system->attachFileSystem(myopen, myclose, myread, 0);
    ERRCHECK(result);

    printf("Buffering...\n\n");

    result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        static bool mute = false;

        if (sound && !channel)
        {
            result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel);
        }

        if (_kbhit())
        {
            key = _getch();

            switch (key)
            {
                case ' ' :
                {
                    if (channel)
                    {
                        bool paused;
                        channel->getPaused(&paused);
                        channel->setPaused(!paused);
                    }
                    break;
                }
                case 'm' :
                case 'M' :
                {
                    if (channel)
                    {
                        channel->getMute(&mute);
                        channel->setMute(!mute);
                    }
                    break;
                }
            }
        }

        system->update();

        if (channel)
        {
            bool         playing = false;
            int          tagsupdated = 0;

            sound->getNumTags(0, &tagsupdated);

            if (tagsupdated)
            {
                printf("\n");
                printf("\n");
                for (;;)
                {
                    FMOD_TAG tag;

                    if (sound->getTag(0, -1, &tag) != FMOD_OK)
                    {
                        break;
                    }

                    if (tag.datatype == FMOD_TAGDATATYPE_STRING)
                    {
                        printf("[%-11s] %s (%d bytes)\n", tag.name, tag.data, tag.datalen);
                        
                        sound->getFormat(&gSoundType, 0, 0, 0);
                    
                        if (!strcmp(tag.name, "ARTIST"))
                        {
                            if (strncmp(gCurrentTrackArtist, (const char *)tag.data, 256))
                            {
                                strncpy(gCurrentTrackArtist, (const char *)tag.data, 256);
                                gUpdateFileName = true;
                            }
                        }
                        if (!strcmp(tag.name, "TITLE"))
                        {
                            if (strncmp(gCurrentTrackTitle, (const char *)tag.data, 256))
                            {
                                strncpy(gCurrentTrackTitle, (const char *)tag.data, 256);
                                gUpdateFileName = true;
                            }
                        }
                    }
                }
                printf("\n");
            }

            result = channel->isPlaying(&playing);
            if (result != FMOD_OK || !playing)
            {
                sound->release();
                sound = 0;               
                channel = 0;
            }
            else
            {
                unsigned int    ms = 0, percent = 0;
                bool            paused = false;
                bool            starving = false;
                FMOD_OPENSTATE  openstate;

                result = sound->getOpenState(&openstate, &percent, &starving, 0);
                ERRCHECK(result);
        
                channel->setVolume(starving ? 0.0f : 1.0f);     /* Don't use mute because the user is setting that. */
                ERRCHECK(result);

                result = channel->getPaused(&paused);
                result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
                printf("Time %02d:%02d:%02d : (%3d%%%) %s SPACE = pause. 'm' = mute. ESC = quit.\r", ms / 1000 / 60, ms / 1000 % 60, ms / 10 % 100, percent, (openstate == FMOD_OPENSTATE_BUFFERING || starving) ? "Buffering..." : openstate == FMOD_OPENSTATE_CONNECTING ? "Connecting..." : paused ? "Paused       " : playing ? "Playing      " : "Stopped      ", percent, starving ? "STARVING" : "        ");

            }
        }

       
        if (sound)
        {
            FMOD_OPENSTATE openstate = FMOD_OPENSTATE_READY;

            sound->getOpenState(&openstate, 0, 0, 0);

            if (openstate == FMOD_OPENSTATE_ERROR)
            {
                sound->release();
                sound = 0;               
                channel = 0;
            }
        }

        if (!sound)
        {
            printf("\n");
            printf("Error occurred or stream ended.  Restarting stream..\n");
            result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound);
            ERRCHECK(result);
            Sleep(1000);
        }

        Sleep(10);

    } while (key != 27);

    printf("\n");

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    return 0;
}
int main(int argc, char *argv[])
{
    FMOD::System    *system;
    FMOD::Sound     *sound;
    FMOD_RESULT      result;
    FMOD_TAG         tag;
    int              numtags, numtagsupdated, count;
    unsigned int     version;

    printf("==================================================================\n");
    printf("ReadTags Example.  Copyright (c) Firelight Technologies 2004-2011.\n");
    printf("==================================================================\n\n");

    /*
        Global Settings
    */
    result = FMOD::System_Create(&system);
    ERRCHECK(result);

    result = system->getVersion(&version);
    ERRCHECK(result);

    if (version < FMOD_VERSION)
    {
        printf("Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", version, FMOD_VERSION);
        getch();
        return 0;
    }

    result = system->init(100, FMOD_INIT_NORMAL, 0);
    ERRCHECK(result);

    /*
        Open the specified file. Use FMOD_CREATESTREAM and FMOD_OPENONLY so it opens quickly
    */
    result = system->createSound("../media/wave.mp3", FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_OPENONLY, 0, &sound);
    ERRCHECK(result);

    /*
        Read and display all tags associated with this file
    */
    for (;;)
    {
        /*
            An index of -1 means "get the first tag that's new or updated".
            If no tags are new or updated then getTag will return FMOD_ERR_TAGNOTFOUND.
            This is the first time we've read any tags so they'll all be new but after we've read them, 
            they won't be new any more.
        */
        if (sound->getTag(0, -1, &tag) != FMOD_OK)
        {
            break;
        }
        if (tag.datatype == FMOD_TAGDATATYPE_STRING)
        {
            printf("%s = %s (%d bytes)\n", tag.name, (char *)tag.data, tag.datalen);
        }
        else
        {
            printf("%s = <binary> (%d bytes)\n", tag.name, tag.datalen);
        }
    }
    printf("\n");

    /*
        Read all the tags regardless of whether they're updated or not. Also show the tag type.
    */
    result = sound->getNumTags(&numtags, &numtagsupdated);
    ERRCHECK(result);
    for (count=0; count < numtags; count++)
    {
        result = sound->getTag(0, count, &tag);
        ERRCHECK(result);

        switch (tag.type)
        {
            case FMOD_TAGTYPE_UNKNOWN :
                printf("FMOD_TAGTYPE_UNKNOWN  ");
                break;

            case FMOD_TAGTYPE_ID3V1 :
                printf("FMOD_TAGTYPE_ID3V1  ");
                break;

            case FMOD_TAGTYPE_ID3V2 :
                printf("FMOD_TAGTYPE_ID3V2  ");
                break;

            case FMOD_TAGTYPE_VORBISCOMMENT :
                printf("FMOD_TAGTYPE_VORBISCOMMENT  ");
                break;

            case FMOD_TAGTYPE_SHOUTCAST :
                printf("FMOD_TAGTYPE_SHOUTCAST  ");
                break;

            case FMOD_TAGTYPE_ICECAST :
                printf("FMOD_TAGTYPE_ICECAST  ");
                break;

            case FMOD_TAGTYPE_ASF :
                printf("FMOD_TAGTYPE_ASF  ");
                break;

            case FMOD_TAGTYPE_FMOD :
                printf("FMOD_TAGTYPE_FMOD  ");
                break;

            case FMOD_TAGTYPE_USER :
                printf("FMOD_TAGTYPE_USER  ");
                break;
        }

        if (tag.datatype == FMOD_TAGDATATYPE_STRING)
        {
            printf("%s = %s (%d bytes)\n", tag.name, (char *)tag.data, tag.datalen);
        }
        else
        {
            printf("%s = ??? (%d bytes)\n", tag.name, tag.datalen);
        }
    }
    printf("\n");

    /*
        Find a specific tag by name. Specify an index > 0 to get access to multiple tags of the same name.
    */
    result = sound->getTag("ARTIST", 0, &tag);
    ERRCHECK(result);
    printf("%s = %s (%d bytes)\n", tag.name, (char *)tag.data, tag.datalen);
    printf("\n");

    /*
        Shut down
    */
    result = sound->release();
    ERRCHECK(result);
    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    return 0;
}