All pastes #3194770 Raw Edit

Someone

public unlisted text v1 · immutable
#3194770 ·published 2015-10-13 10:11 UTC
rendered paste body
/*==============================================================================
Net Stream Example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2015.

This example shows how to play streaming audio from an Internet source
==============================================================================*/
#include "fmod.hpp"
#include "common.h"

static FMOD_RESULT F_CALLBACK dummy_open(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
static FMOD_RESULT F_CALLBACK dummy_close(FMOD_CODEC_STATE *codec);
static FMOD_RESULT F_CALLBACK dummy_read(FMOD_CODEC_STATE *codec, void *buffer, unsigned int size, unsigned int *read);
static FMOD_RESULT F_CALLBACK dummy_setposition(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype);

static FMOD_CODEC_DESCRIPTION dummy_codec_desc =
{
    "FMOD dummy plugin",                 // Name.
    0x00010000,                         // Version 0xAAAABBBB   A = major, B = minor.
    0,                                  // Don't force everything using this codec to be a stream
    FMOD_TIMEUNIT_PCM,                  // The time format we would like to accept into setposition/getposition.
    &dummy_open,                         // Open callback.
    &dummy_close,                        // Close callback.
    &dummy_read,                         // Read callback.
    0,                                  // Getlength callback.  (If not specified FMOD return the length in FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES units based on the lengthpcm member of the FMOD_CODEC structure).
    &dummy_setposition,                  // Setposition callback.
    0,                                  // Getposition callback. (only used for timeunit types that are not FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS and FMOD_TIMEUNIT_PCMBYTES).
    0                                   // Sound create callback (don't need it)
};


F_DECLSPEC F_DLLEXPORT FMOD_CODEC_DESCRIPTION * F_API FMODGetDummyCodecDescription()
{
    return &dummy_codec_desc;
}

static FMOD_RESULT F_CALLBACK dummy_open(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo)
{
    return FMOD_ERR_FORMAT;
}

static FMOD_RESULT F_CALLBACK dummy_close(FMOD_CODEC_STATE *codec)
{
    codec->plugindata = 0;
    return FMOD_OK;
}

static FMOD_RESULT F_CALLBACK dummy_read(FMOD_CODEC_STATE *codec, void *buffer, unsigned int size, unsigned int *read)
{
    return FMOD_ERR_FILE_BAD;

}

static FMOD_RESULT F_CALLBACK dummy_setposition(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
{
    return FMOD_ERR_FILE_BAD;
}

int FMOD_Main()
{
    FMOD::System    *system = 0;
    FMOD::Sound     *sound = 0;
    FMOD::Channel   *channel = 0;
    FMOD_RESULT      result = FMOD_OK;
    FMOD_OPENSTATE   openstate = FMOD_OPENSTATE_READY;
    unsigned int     version = 0;
    void            *extradriverdata = 0;
    const int        tagcount = 4;
    int              tagindex = 0;
    char             tagstring[tagcount][128] = { 0 };
    
    Common_Init(&extradriverdata);
    
    /*
        Create a System object and initialize.
    */
    result = FMOD::System_Create(&system);
    ERRCHECK(result);

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

    if (version < FMOD_VERSION)
    {
        Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION);
    }

    result = system->init(1, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);

    result = system->registerCodec(FMODGetDummyCodecDescription(), 0, 599);
    ERRCHECK(result);

    /* Increase the file buffer size a little bit to account for Internet lag. */
    result = system->setStreamBufferSize(128*1024, FMOD_TIMEUNIT_RAWBYTES);
    ERRCHECK(result);

    FMOD_CREATESOUNDEXINFO info;
    memset(&info, 0, sizeof(info));
    info.cbsize = sizeof(info);

    const char* url = "http://shoutmedia.abc.net.au:10426";
    url = "http://uploadserver.oss.aliyuncs.com/745/699745/1443431047-55.mp3";
    result = system->createSound(url, FMOD_CREATESTREAM| FMOD_NONBLOCKING, &info, &sound);
    ERRCHECK(result);

    /*
        Main loop
    */
    do
    {
        unsigned int    pos = 0;
        unsigned int    percent = 0;
        bool            playing = false;
        bool            paused = false;
        bool            starving = false;
        const char     *state = "Stopped";
        
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            if (channel)
            {
                bool paused = false;
                
                result = channel->getPaused(&paused);
                ERRCHECK(result);
                result = channel->setPaused(!paused);
                ERRCHECK(result);
            }
        }
        
        result = system->update();
        ERRCHECK(result);
        
        result = sound->getOpenState(&openstate, &percent, &starving, 0);
        ERRCHECK(result);
        
        if (channel)
        {
            FMOD_TAG tag;
        
            /*
                Read any tags that have arrived, this could happen if a radio station switches
                to a new song.
            */
            while (sound->getTag(0, -1, &tag) == FMOD_OK)
            {
                if (tag.datatype == FMOD_TAGDATATYPE_STRING)
                {
                    sprintf(tagstring[tagindex], "%s = '%s' (%d bytes)", tag.name, (char *)tag.data, tag.datalen);
                    tagindex = (tagindex + 1) % tagcount;
                }
                else if (tag.type == FMOD_TAGTYPE_FMOD)
                {
                    /* When a song changes, the sample rate may also change, so compensate here. */
                    if (!strcmp(tag.name, "Sample Rate Change"))
                    {
                        float frequency = *((float *)tag.data);
                        
                        result = channel->setFrequency(frequency);
                        ERRCHECK(result);
                    }
                }
            }
            
            result = channel->getPaused(&paused);
            ERRCHECK(result);
            
            result = channel->isPlaying(&playing);
            ERRCHECK(result);
            
            result = channel->getPosition(&pos, FMOD_TIMEUNIT_MS);
            ERRCHECK(result);
            
            /* Silence the stream until we have sufficient data for smooth playback. */
            result = channel->setMute(starving);
            ERRCHECK(result);
        }
        else
        {
             /* This may fail if the stream isn't ready yet, so don't check the error code. */
            if (openstate == FMOD_OPENSTATE_READY)
            {
                result = system->playSound(sound, 0, false, &channel);
                ERRCHECK(result);
            }
        }
        
        if (openstate == FMOD_OPENSTATE_BUFFERING)
        {
            state = "Buffering...";
        }
        else if (openstate == FMOD_OPENSTATE_CONNECTING)
        {
            state = "Connecting...";
        }
        else if (paused)
        {
            state = "Paused";
        }
        else if (playing)
        {
            state = "Playing";
        }

        Common_Draw("==================================================");
        Common_Draw("Net Stream Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2015.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to toggle pause", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw("Time = %02d:%02d:%02d", pos / 1000 / 60, pos / 1000 % 60, pos / 10 % 100);
        Common_Draw("State = %s %s", state, starving ? "(STARVING)" : "");
        Common_Draw("Buffer Percentage = %d", percent);
        Common_Draw("");
        Common_Draw("Tags:");
        for (int i = tagindex; i < (tagindex + tagcount); i++)
        {
            Common_Draw("%s", tagstring[i % tagcount]);
            Common_Draw("");
        }

        Common_Sleep(50);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Stop the channel, then wait for it to finish opening before we release it.
    */    
    if (channel)
    {
        result = channel->stop();
        ERRCHECK(result);
    }

    do
    {
        Common_Update();
        Common_Draw("Waiting for sound to finish opening before trying to release it....", Common_BtnStr(BTN_ACTION1));
        Common_Sleep(50);
        
        result = system->update();
        ERRCHECK(result);

        result = sound->getOpenState(&openstate, 0, 0, 0);
        ERRCHECK(result);
    } while (openstate != FMOD_OPENSTATE_READY);

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

    Common_Close();
    
    return 0;
}