Example #1
0
void MusicEffect::Render(RenderBuffer &buffer,
    int bars, const std::string& type,
    int sensitivity, bool scale,
    const std::string& scalenotes, int offsetx,
    int startnote, int endnote,
    const std::string& colourtreatment,
    bool fade)
{
    // no point if we have no media
    if (buffer.GetMedia() == NULL)
    {
        return;
    }

    int nType = DecodeType(type);
    int nTreatment = DecodeColourTreatment(colourtreatment);
    int nScaleNotes = DecodeScaleNotes(scalenotes);

    // Grab our cache
    MusicRenderCache *cache = (MusicRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new MusicRenderCache();
        buffer.infoCache[id] = cache;
    }
    int &_bars = cache->_bars;
    int &_startNote = cache->_startNote;
    int &_endNote = cache->_endNote;
    int &_type = cache->_type;
    int &_offsetx = cache->_offsetx;
    bool &_scale = cache->_scale;
    int &_sensitivity = cache->_sensitivity;
    int &_scalenotes = cache->_scalenotes;
    bool &_fade = cache->_fade;
    int& _colourTreatment = cache->_colourTreatment;
    std::vector<std::list<MusicEvent*>*>& _events = cache->_events;

    int actualbars = std::min(bars, std::min(endnote - startnote + 1, buffer.BufferWi - offsetx));
    int notesperbar = (endnote - startnote + 1) / actualbars;
    int actualendnote = startnote + std::min(endnote, actualbars * notesperbar);
    int lightsperbar = 0.5 + (float)(buffer.BufferWi - offsetx) / (float)actualbars;

    // Check for config changes which require us to reset
    if (buffer.needToInit || _bars != bars || _type != nType || _startNote != startnote || 
        _endNote != endnote || _offsetx != offsetx || _scale != scale || 
        _scalenotes != nScaleNotes || _sensitivity != sensitivity || _colourTreatment != nTreatment || _fade != fade)
    {
        buffer.needToInit = false;
        _bars = bars;
        _fade = fade;
        _startNote = startnote;
        _endNote = endnote;
        _colourTreatment = nTreatment;
        _type = nType;
        _offsetx = offsetx;
        _scale = scale;
        _sensitivity = sensitivity;
        _scalenotes = nScaleNotes;
        cache->ClearEvents();
        // We limit bars to the width of the model less the x offset

        CreateEvents(buffer, _events, _startNote, actualendnote, actualbars, _scalenotes, _sensitivity);
    }

    int per = 1;
    if (_scale)
    {
        per = lightsperbar;
    }

    try
    {
        for (int x = 0; x < _events.size(); x++)
        {
            for (int i = 0; i < per; i++)
            {
                switch (_type)
                {
                case 1:
                    RenderMorph(buffer, (x*per) + i + _offsetx, _bars, _startNote, _endNote, *_events[x], _colourTreatment, false, fade);
                    break;
                case 2:
                    RenderMorph(buffer, (x*per) + i + _offsetx, _bars, _startNote, _endNote, *_events[x], _colourTreatment, true, fade);
                    break;
                case 3:
                    RenderCollide(buffer, (x*per) + i + _offsetx, _bars, _startNote, _endNote, true /* collide */, *_events[x], _colourTreatment, fade);
                    break;
                case 4:
                    RenderCollide(buffer, (x*per) + i + _offsetx, _bars, _startNote, _endNote, false /* uncollide */,* _events[x], _colourTreatment, fade);
                    break;
                case 5:
                    RenderOn(buffer, (x*per) + i + _offsetx, _bars, _startNote, _endNote, *_events[x], _colourTreatment, fade);
                    break;
                }
            }
        }
    }
    catch (...)
    {
        // This is here to let me catch any exceptions and stop the exception causing the render thread to die
        //int a = 0;
    }
}
Example #2
0
void MusicEffect::CreateEvents(RenderBuffer& buffer, std::vector<std::list<MusicEvent*>*>& events, int startNote, int endNote, int bars, int scalenotes, int sensitivity)
{
    // must have media
    if (buffer.GetMedia() == NULL)
    {
        return;
    }

    float notesperbar = ((float)endNote - (float)startNote + 1.0) / (float)bars;

    // use notes per bar
    // use multiple notes of data per output string using the maximum of these notes intensities
    std::map<int /*bar*/, std::map<int /*frame*/, float>> data;
    std::map<int /*bar*/, float> max;
    float overallmax = 0.0;

    for (int b = 0; b < bars; b++)
    {
        max[b] = 0.0;
    }

    // go through each frame and extract the data i need
    for (int f = buffer.curEffStartPer; f <= buffer.curEffEndPer; f++)
    {
        std::list<float>* pdata = buffer.GetMedia()->GetFrameData(f, FRAMEDATATYPE::FRAMEDATA_VU, "");

        auto pn = pdata->begin();

        // skip to start note
        for (int i = 0; i < startNote; i++)
        {
            ++pn;
        }

        for (int b = 0; b < bars && pn != pdata->end(); b++)
        {
            float val = 0.0;
            for (int n = 0; n < (int)notesperbar; n++)
            {
                val = std::max(val, *pn);
                ++pn;
            }
            data[b][f] = val;
            max[b] = std::max(max[b], val);
            overallmax = std::max(overallmax, val);
        }
    }

    for (int b = 0; b < bars; b++)
    {
        events.push_back(new std::list<MusicEvent*>());
        float notesensitivity;
        if (scalenotes == 1)
        {
            notesensitivity = (float)sensitivity / 100.0;
        }
        else if (scalenotes == 2)
        {
            notesensitivity = (float)sensitivity / 100.0 * max[b];
        }
        else
        {
            notesensitivity = (float)sensitivity / 100.0 * overallmax;
        }
        int startframe = -1;
        // extract the value for this note
        int frame = buffer.curEffStartPer;
        for (auto f = data[b].begin(); f != data[b].end(); ++f)
        {
            if (f->second > notesensitivity)
            {
                startframe = frame;

                while (f != data[b].end() && f->second > notesensitivity)
                {
                    ++f;
                    frame++;
                }
                --f;
                frame--;
                if (frame - startframe >= MINIMUMEVENTLENGTH)
                {
                    events[b]->push_back(new MusicEvent(startframe, frame - startframe));
                }
            }
            frame++;
        }
    }
}
Example #3
0
void FireworksEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int Number_Explosions = SettingsMap.GetInt("SLIDER_Fireworks_Explosions", 16);
    int Count = SettingsMap.GetInt("SLIDER_Fireworks_Count", 50);
    float Velocity = SettingsMap.GetDouble("SLIDER_Fireworks_Velocity", 2.0f);
    int Fade = SettingsMap.GetInt("SLIDER_Fireworks_Fade", 50);

    float f = 0.0;
    bool useMusic = SettingsMap.GetBool("CHECKBOX_Fireworks_UseMusic", false);
    float sensitivity = (float)SettingsMap.GetInt("SLIDER_Fireworks_Sensitivity", 50) / 100.0;
    bool useTiming = SettingsMap.GetBool("CHECKBOX_FIRETIMING", false);
    wxString timing = SettingsMap.Get("CHOICE_FIRETIMINGTRACK", "");
    if (timing == "") useTiming = false;
    if (useMusic)
    {
        if (buffer.GetMedia() != nullptr) {
            std::list<float>* pf = buffer.GetMedia()->GetFrameData(buffer.curPeriod, FRAMEDATA_HIGH, "");
            if (pf != nullptr)
            {
                f = *pf->begin();
            }
        }
    }

    FireworksRenderCache *cache = (FireworksRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new FireworksRenderCache();
        buffer.infoCache[id] = cache;
    }
    
    int& next = cache->next;
    int& sincelasttriggered = cache->sincelasttriggered;
    int x25,x75,y25,y75;
    //float velocity = 3.5;
    int ColorIdx;
    float v;
    HSVValue hsv;
    size_t colorcnt = buffer.GetColorCount();
    
    if (buffer.needToInit) {
        SetPanelTimingTracks();
        cache->sincelasttriggered = 0;
        cache->next = 0;
        buffer.needToInit = false;
        for(int i=0; i<maxFlakes; i++) {
            cache->fireworkBursts[i]._bActive = false;
        }
        for (int x = 0; x < Number_Explosions; x++) {
            double start = -1;
            if (!useMusic)
            {
                start = buffer.curEffStartPer + buffer.rand01() * (buffer.curEffEndPer - buffer.curEffStartPer);
            }
            x25=(int)buffer.BufferWi*0.25;
            x75=(int)buffer.BufferWi*0.75;
            y25=(int)buffer.BufferHt*0.25;
            y75=(int)buffer.BufferHt*0.75;
            int startX;
            int startY;
            if((x75-x25)>0) startX = x25 + rand()%(x75-x25); else startX=0;
            if((y75-y25)>0) startY = y25 + rand()%(y75-y25); else startY=0;
            
            // Create a new burst
            ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
            for(int i=0; i<Count; i++) {
                cache->fireworkBursts[x * Count + i].Reset(startX, startY, false, Velocity, ColorIdx, start);
            }
        }

        if (timing != "")
        {
            effect->GetParentEffectLayer()->GetParentElement()->GetSequenceElements()->AddRenderDependency(timing.ToStdString(), buffer.cur_model);
        }
    }

    if (useMusic)
    {
        // only trigger a firework if music is greater than the sensitivity
        if (f > sensitivity)
        {
            // trigger if it was not previously triggered or has been triggered for REPEATTRIGGER frames
            if (sincelasttriggered == 0 || sincelasttriggered > REPEATTRIGGER)
            {
                // activate all the particles in the next firework
                for (int j = 0; j < Count; j++)
                {
                    cache->fireworkBursts[Count*next + j]._bActive = true;
                    buffer.palette.GetHSV(cache->fireworkBursts[Count*next + j]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                    cache->fireworkBursts[Count*next + j]._hsv = hsv;
                }

                // use the next firework next time
                next++;
                if (next == Number_Explosions)
                {
                    next = 0;
                }
            }

            // if music is over the trigger level for REPEATTRIGGER frames then we will trigger another firework
            sincelasttriggered++;
            if (sincelasttriggered > REPEATTRIGGER)
            {
                sincelasttriggered = 0;
            }
        }
        else
        {
            // not triggered so clear last triggered counter
            sincelasttriggered = 0;
        }
    }

    if (useTiming)
    {
        if (mSequenceElements == nullptr)
        {
            // no timing tracks ... this shouldnt happen
        }
        else
        {
            // Load the names of the timing tracks
            Element* t = nullptr;
            for (size_t l = 0; l < mSequenceElements->GetElementCount(); l++)
            {
                Element* e = mSequenceElements->GetElement(l);
                if (e->GetEffectLayerCount() == 1 && e->GetType() == ELEMENT_TYPE_TIMING)
                {
                    if (e->GetName() == timing)
                    {
                        t = e;
                        break;
                    }
                }
            }

            if (t == nullptr)
            {
                // timing track not found ... this shouldnt happen
            }
            else
            {
                sincelasttriggered = 0;
                EffectLayer* el = t->GetEffectLayer(0);
                for (int j = 0; j < el->GetEffectCount(); j++)
                {
                    if (buffer.curPeriod == el->GetEffect(j)->GetStartTimeMS() / buffer.frameTimeInMs ||
                        buffer.curPeriod == el->GetEffect(j)->GetEndTimeMS() / buffer.frameTimeInMs)
                    {
                        // activate all the particles in the next firework
                        for (int k = 0; k < Count; k++)
                        {
                            cache->fireworkBursts[Count*next + k]._bActive = true;
                            buffer.palette.GetHSV(cache->fireworkBursts[Count*next + k]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                            cache->fireworkBursts[Count*next + k]._hsv = hsv;
                        }

                        // use the next firework next time
                        next++;
                        if (next == Number_Explosions)
                        {
                            next = 0;
                        }
                        break;
                    }
                }
            }
        }
    }

    for (int i=0; i<(Count*Number_Explosions); i++) {
        if (!useMusic && !useTiming)
        {
            if (cache->fireworkBursts[i].startPeriod == buffer.curPeriod) {
                cache->fireworkBursts[i]._bActive = true;
                buffer.palette.GetHSV(cache->fireworkBursts[i]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                cache->fireworkBursts[i]._hsv = hsv;
            }
        }

        // ... active flakes:
        if (cache->fireworkBursts[i]._bActive)
        {
            // Update position
            cache->fireworkBursts[i]._x += cache->fireworkBursts[i]._dx;
            cache->fireworkBursts[i]._y += (-cache->fireworkBursts[i]._dy - cache->fireworkBursts[i]._cycles*cache->fireworkBursts[i]._cycles/10000000.0);
            // If this flake run for more than maxCycle or this flake is out of bounds, time to switch it off
            cache->fireworkBursts[i]._cycles+=20;
            if (cache->fireworkBursts[i]._cycles >= 10000 || cache->fireworkBursts[i]._y >= buffer.BufferHt || cache->fireworkBursts[i]._y < 0 ||
                cache->fireworkBursts[i]._x < 0. || cache->fireworkBursts[i]._x >= buffer.BufferWi)
            {
                cache->fireworkBursts[i]._bActive = false;
                if (useMusic)
                {
                    cache->fireworkBursts[i].Reset();
                }
                continue;
            }
        }
        if(cache->fireworkBursts[i]._bActive == true)
        {
            v = ((Fade*10.0)-cache->fireworkBursts[i]._cycles)/(Fade*10.0);
            if (v<0) v=0.0;
            if (buffer.allowAlpha) {
                xlColor c(cache->fireworkBursts[i]._hsv);
                c.alpha = 255.0 * v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, c);
            } else {
                hsv=cache->fireworkBursts[i]._hsv;
                hsv.value=v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, hsv);
            }
        }
    }
}