⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multivoc.c

📁 An interactive water fountain. A realistic water source in your pocket with full control. Contro
💻 C
📖 第 1 页 / 共 5 页
字号:
            {                MV_CallBackFunc(voice->callbackval);            }        }    }    return MV_MixPage;}/*---------------------------------------------------------------------   Function: MV_GetNextVOCBlock   Interperate the information of a VOC format sound file.---------------------------------------------------------------------*/static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice){    char *ptr;    int32_t blocktype;    int32_t lastblocktype;    uint32_t blocklength = 0;    uint32_t samplespeed = 0;    uint32_t tc = 0;    int32_t packtype;    int32_t voicemode;    int32_t done;    unsigned       BitsPerSample;    unsigned       Channels;    unsigned       Format;    if (voice->BlockLength > 0)    {        voice->position    -= voice->length;        voice->sound       += voice->length >> 16;        if (voice->bits == 16)        {            voice->sound += voice->length >> 16;        }        voice->length       = min(voice->BlockLength, 0x8000);        voice->BlockLength -= voice->length;        voice->length     <<= 16;        return(KeepPlaying);    }    if ((voice->length > 0) && (voice->LoopEnd != NULL) && (voice->LoopStart != NULL))    {        voice->BlockLength  = voice->LoopSize;        voice->sound        = voice->LoopStart;        voice->position     = 0;        voice->length       = min(voice->BlockLength, 0x8000);        voice->BlockLength -= voice->length;        voice->length     <<= 16;        return(KeepPlaying);    }    ptr = (char *)voice->NextBlock;    voice->Playing = TRUE;    voicemode = 0;    lastblocktype = 0;    packtype = 0;    done = FALSE;    while (!done)    {        // Stop playing if we get a NULL pointer        if (ptr == NULL)        {            voice->Playing = FALSE;            done = TRUE;            break;        }        blocktype = (int32_t)*ptr;        blocklength = (*(uint32_t *)(ptr + 1)) & 0x00ffffff;        ptr += 4;        switch (blocktype)        {        case 0 :            // End of data            if ((voice->LoopStart == NULL) || ((uint32_t *)voice->LoopStart >= (uint32_t *)(ptr - 4)))            {                voice->Playing = FALSE;                done = TRUE;            }            else            {                voice->BlockLength  = (char*)(ptr - 4) - voice->LoopStart;                voice->sound        = voice->LoopStart;                voice->position     = 0;                voice->length       = min(voice->BlockLength, 0x8000);                voice->BlockLength -= voice->length;                voice->length     <<= 16;                return(KeepPlaying);            }            break;        case 1 :            // Sound data block            voice->bits  = 8;            if (lastblocktype != 8)            {                tc = (uint32_t)*ptr << 8;                packtype = *(ptr + 1);            }            ptr += 2;            blocklength -= 2;            samplespeed = 256000000L / (65536 - tc);            // Skip packed or stereo data            if ((packtype != 0) || (voicemode != 0))            {                ptr += blocklength;            }            else            {                done = TRUE;            }            voicemode = 0;            break;        case 2 :            // Sound continuation block            samplespeed = voice->SamplingRate;            done = TRUE;            break;        case 3 :            // Silence            // Not implimented.            ptr += blocklength;            break;        case 4 :            // Marker            // Not implimented.            ptr += blocklength;            break;        case 5 :            // ASCII string            // Not implimented.            ptr += blocklength;            break;        case 6 :            // Repeat begin            if (voice->LoopEnd == NULL)            {                voice->LoopCount = *(uint16_t *)ptr;                voice->LoopStart = (char *)(ptr + blocklength);            }            ptr += blocklength;            break;        case 7 :            // Repeat end            ptr += blocklength;            if (lastblocktype == 6)            {                voice->LoopCount = 0;            }            else            {                if ((voice->LoopCount > 0) && (voice->LoopStart != NULL))                {                    ptr = (char *)voice->LoopStart;                    if (voice->LoopCount < 0xffff)                    {                        voice->LoopCount--;                        if (voice->LoopCount == 0)                        {                            voice->LoopStart = NULL;                        }                    }                }            }            break;        case 8 :            // Extended block            voice->bits  = 8;            tc = *(uint16_t *)ptr;            packtype = *(ptr + 2);            voicemode = *(ptr + 3);            ptr += blocklength;            break;        case 9 :            // New sound data block            samplespeed = *(uint32_t *)ptr;            BitsPerSample = (unsigned)*(ptr + 4);            Channels = (unsigned)*(ptr + 5);            Format = (unsigned)*(uint16_t *)(ptr + 6);            if ((BitsPerSample == 8) && (Channels == 1) && (Format == VOC_8BIT))            {                ptr         += 12;                blocklength -= 12;                voice->bits  = 8;                done         = TRUE;            }            else if ((BitsPerSample == 16) && (Channels == 1) && (Format == VOC_16BIT))            {                ptr         += 12;                blocklength -= 12;                voice->bits  = 16;                done         = TRUE;            }            else            {                ptr += blocklength;            }            break;        default :            // Unknown data.  Probably not a VOC file.            voice->Playing = FALSE;            done = TRUE;            break;        }        lastblocktype = blocktype;    }    if (voice->Playing)    {        voice->NextBlock    = (char *)(ptr + blocklength);        voice->sound        = (char *)ptr;        voice->SamplingRate = samplespeed;        voice->RateScale    = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;        // Multiply by MixBufferSize - 1        voice->FixedPointBufferSize = (voice->RateScale * MixBufferSize) -                                      voice->RateScale;        if (voice->LoopEnd != NULL)        {            if (blocklength > (uintptr_t)voice->LoopEnd)            {                blocklength = (uintptr_t)voice->LoopEnd;            }            else            {                voice->LoopEnd = (char *)blocklength;            }            voice->LoopStart = voice->sound + (uintptr_t)voice->LoopStart;            voice->LoopEnd   = voice->sound + (uintptr_t)voice->LoopEnd;            voice->LoopSize  = voice->LoopEnd - voice->LoopStart;        }        if (voice->bits == 16)        {            blocklength /= 2;        }        voice->position     = 0;        voice->length       = min(blocklength, 0x8000);        voice->BlockLength  = blocklength - voice->length;        voice->length     <<= 16;        MV_SetVoiceMixMode(voice);        return(KeepPlaying);    }    return(NoMoreData);}/*---------------------------------------------------------------------   Function: MV_GetNextDemandFeedBlock   Controls playback of demand fed data.---------------------------------------------------------------------*/playbackstatus MV_GetNextDemandFeedBlock(VoiceNode *voice){    if (voice->BlockLength > 0)    {        voice->position    -= voice->length;        voice->sound       += voice->length >> 16;        voice->length       = min(voice->BlockLength, 0x8000);        voice->BlockLength -= voice->length;        voice->length     <<= 16;        return(KeepPlaying);    }    if (voice->DemandFeed == NULL)    {        return(NoMoreData);    }    voice->position     = 0;    (voice->DemandFeed)(&voice->sound, &voice->BlockLength);    voice->length       = min(voice->BlockLength, 0x8000);    voice->BlockLength -= voice->length;    voice->length     <<= 16;    if ((voice->length > 0) && (voice->sound != NULL))    {        return(KeepPlaying);    }    return(NoMoreData);}/*---------------------------------------------------------------------   Function: MV_GetNextRawBlock   Controls playback of demand fed data.---------------------------------------------------------------------*/playbackstatus MV_GetNextRawBlock(VoiceNode *voice){    if (voice->BlockLength <= 0)    {        if (voice->LoopStart == NULL)        {            voice->Playing = FALSE;            return(NoMoreData);        }        voice->BlockLength = voice->LoopSize;        voice->NextBlock   = voice->LoopStart;        voice->length = 0;        voice->position = 0;    }    voice->sound        = voice->NextBlock;    voice->position    -= voice->length;    voice->length       = min(voice->BlockLength, 0x8000);    voice->NextBlock   += voice->length;    if (voice->bits == 16)    {        voice->NextBlock += voice->length;    }    voice->BlockLength -= voice->length;    voice->length     <<= 16;    return(KeepPlaying);}/*---------------------------------------------------------------------   Function: MV_GetNextWAVBlock   Controls playback of demand fed data.---------------------------------------------------------------------*/playbackstatus MV_GetNextWAVBlock(VoiceNode *voice){    if (voice->BlockLength <= 0)    {        if (voice->LoopStart == NULL)        {            voice->Playing = FALSE;            return(NoMoreData);        }        voice->BlockLength = voice->LoopSize;        voice->NextBlock   = voice->LoopStart;        voice->length      = 0;        voice->position    = 0;    }    voice->sound        = voice->NextBlock;    voice->position    -= voice->length;    voice->length       = min(voice->BlockLength, 0x8000);    voice->NextBlock   += voice->length;    if (voice->bits == 16)    {        voice->NextBlock += voice->length;    }    voice->BlockLength -= voice->length;    voice->length     <<= 16;    return(KeepPlaying);}/*---------------------------------------------------------------------   Function: MV_GetNextOGGBlock   Controls playback of demand fed data.---------------------------------------------------------------------*/void downsample(char *ptr,int32_t size,int32_t factor){    int16_t *pti=(int16_t *)ptr;int32_t i,j,sum;    for (i=0;i<size>>factor;i++)    {        sum=0;        for (j=0;j<1<<factor;j++)sum+=pti[(i<<factor)+j];        pti[i]=sum>>factor;    }}playbackstatus MV_GetNextOGGBlock(VoiceNode *voice){    int32_t sz;    int32_t size=0;    int32_t section,result;//    initprintf("_%d %d, %d\n",voice->callbackval,voice->position,voice->BlockLength);    if (voice->BlockLength <= 0)    {        if (voice->LoopStart == NULL)        {//            initprintf("END %d\n",voice->callbackval);            voice->Playing = FALSE;            return(NoMoreData);        }//        initprintf("repeat 2\n");        voice->BlockLength = voice->LoopSize;        voice->length      = 0;        voice->position    = 0;        ov_pcm_seek(&voice->OGGstream.oggStream,0);    }    voice->position    -= voice->length;    sz=voice->length    = min(voice->BlockLength, 0x8000);    voice->BlockLength -= voice->length;    voice->length     <<= 16;    sz<<=voice->downsample+1;    while (size<sz)    {        result=ov_read(&voice->OGGstream.oggStream,voice->bufsnd+(size>>voice->downsample),sz-size,0,2,1,&section);        if (result> 0)        {            downsample(voice->bufsnd+(size>>voice->downsample),result,voice->downsample);            size+=result;        }        else if (result==0)        {//           initprintf("!repeat %d\n",voice->callbackval);            voice->BlockLength=0;            voice->length=size<<16;break;        }        else        {            initprintf("#%d\n",result);            break;        }    }    voice->sound=voice->bufsnd;    return(KeepPlaying);}/*---------------------------------------------------------------------   Function: MV_ServiceRecord   Starts recording of the waiting buffer.---------------------------------------------------------------------*/#if 0static void MV_ServiceRecord(void){    if (MV_RecordFunc)    {        MV_RecordFunc(MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize, MixBufferSize);    }    // Toggle which buffer we'll mix next    MV_MixPage++;    if (MV_MixPage >= NumberOfBuffers)    {        MV_MixPage = 0;    }}#endif/*---------------------------------------------------------------------   Function: MV_GetVoice   Locates the voice with the specified handle.---------------------------------------------------------------------*/VoiceNode *MV_GetVoice(int32_t handle){    VoiceNode *voice;    unsigned  flags;    flags = DisableInterrupts();    for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next)    {        if (handle == voice->handle)        {            break;        }    }    RestoreInterrupts(flags);    if (voice == &VoiceList)    {        MV_SetErrorCode(MV_VoiceNotFound);        voice = NULL;    }    return(voice);}/*---------------------------------------------------------------------   Function: MV_VoicePlaying

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -