Improvements for the Sonique Visualiser

Started by I Ate Minecraft,

I Ate Minecraft

So I was thinking, since the base resolution of the Sonique vis interface is super low, could it be possible to add a flag that newer visualisers can set that will give high-res info, that way, it is backwards-compatible, if the vis doesn't give the flag, then it is an older one, otherwise it supports high-res spectrum and waveform data.

This could then be paired with an info block that can be retrieved (possibly through QueryInt), which would give the following info:
- waveform length + max/min value magnitude
- spectrum length + max/min value magnitude
- Sample rate

Another improvement would be allowing left click and right click, because the Clicked function has a buttons parameter, but as far as I can figure out, it only allows middle click.

On a side note: How hard would it be to have XM Play scan one file for multiple addon types? For instance a visualiser combined with a DSP plugin. Would there be code problems like mem violations, or other problematic/unstable things?

Would love to hear your thoughts Ian!

Ian @ un4seen

Quote from: I Ate MinecraftOn a side note: How hard would it be to have XM Play scan one file for multiple addon types? For instance a visualiser combined with a DSP plugin. Would there be code problems like mem violations, or other problematic/unstable things?

While technically possible, I don't think that'd work very well because the user would then need to enable the plugin in 2 places (eg. in DSP options and vis window). But it is possible for vis plugins to access the XMPlay plugin APIs via QueryInt("xmplay:interface"). The cover art plugin does that, so you can check its source code for an example:

   https://github.com/schellingb/xmp-coverart/blob/17379dd2c7292cc3ab01c3efc30e473b43863157/xmp-coverart.cpp#L1611

Quote from: I Ate MinecraftSo I was thinking, since the base resolution of the Sonique vis interface is super low, could it be possible to add a flag that newer visualisers can set that will give high-res info, that way, it is backwards-compatible, if the vis doesn't give the flag, then it is an older one, otherwise it supports high-res spectrum and waveform data.

This could then be paired with an info block that can be retrieved (possibly through QueryInt), which would give the following info:
- waveform length + max/min value magnitude
- spectrum length + max/min value magnitude
- Sample rate

Something like that should be possible. I'll look into it and hopefully come back with something for you to try. In the meantime, the sample rate is available from the XMPFUNC_STATUS:GetFormat function (in the XMPlay plugin APIs).

Quote from: I Ate MinecraftAnother improvement would be allowing left click and right click, because the Clicked function has a buttons parameter, but as far as I can figure out, it only allows middle click.

The left button is currently used for dragging/moving the window and the right button for the vis selection menu.

I Ate Minecraft

Quote from: Ian @ un4seenWhile technically possible, I don't think that'd work very well because the user would then need to enable the plugin in 2 places

Understandable, and if there are workarounds that are easier for the user, that would make their lives a lot easier.

Quote from: Ian @ un4seenBut it is possible for vis plugins to access the XMPlay plugin APIs via QueryInt("xmplay:interface"). The cover art plugin does that, so you can check its source code

I didn't know that, that sounds really, really useful. I will definitely check it out!

Quote from: Ian @ un4seenSomething like that should be possible. I'll look into it and hopefully come back with something for you to try. In the meantime, the sample rate is available from the XMPFUNC_STATUS:GetFormat function (in the XMPlay plugin APIs).

Thanks a bunch, this gives me a whole lot of new ideas!

As for the plugin its self, it is pretty much done (the FFT version that is), I am basically just interpolating the sample data, and doing some scaling, windowing, and smoothing.
Here is a picture of how it looks:

Ian @ un4seen

Here's something for you to try:

    www.un4seen.com/stuff/xmplay.exe

It extends the VisData struct like this:

typedef struct
{
    unsigned long    MillSec;            // Sonique sets this to the time stamp of end this block of data
    union {
        struct { // Sonique standard
            char            Waveform[2][512];    // Sonique sets this to the PCM data being outputted at this time
            unsigned char    Spectrum[2][256];    // Sonique sets this to a lowfidely version of the spectrum data being outputted at this time
        };
        struct { // XMPlay extended
            unsigned long    NumSamples;            // number of samples in Waveform
            float*            Waveform[2];        // left & right PCM data (xNumSamples)
            float*            Spectrum[2];        // left & right FFT data (xNumSamples/2)
        } ex;
    };
} VisData;

The extended stuff is enabled via a new QueryInt("xmplay:setvisdataex") option, set to the number of wanted samples (one of 512/1024/2048/4096). For example, like this:

int NumSamples = 1024;
if (queryinterface->QueryInt("xmplay:setvisdataex", &NumSamples)) {
    // succeeded, will take effect in next Render call
}

It will default to standard mode each time a plugin in activated (the setting is not saved). ex.Waveform[1] and ex.Spectrum[1] will be NULL when the output is mono.

This stuff is totally untested so far, so please report how you get on with it.

I Ate Minecraft


I Ate Minecraft

Just getting to this now, errands and power outages, two things nobody wants :)

I Ate Minecraft

#6
Ok so, I have implemented the new version into my code, and while it works, it seems that the waveform is WAY smaller than the normal one. Do you already normalise its value before sending it? Also is the maximum requestable value capped at 4096?

Ian @ un4seen

Yes, the extended floating-point values will be smaller (+/-1.0 range) because they don't need to be scaled to fit like the standard 8-bit integers. Note the standard "Spectrum" values are also multiplied by 10 (to make low values - which most of it is - more visible), so the extended values may be up to 2560 (10x256) times smaller than them. Also note the floating-point values may exceed the +/-1.0 range when the output is set to 32-bit floating-point (in the "Output" options) because the sample data isn't capped until sent to the device.

The number of samples is currently limited to 4096 (as it is for the built-in spectrum displays too).