getmusicbee.com

Support => Developers' Area => MusicBee API => Topic started by: kamen on June 04, 2024, 06:58:14 PM

Title: Getting the raw audio samples data
Post by: kamen on June 04, 2024, 06:58:14 PM
Hi Steven!

What do you think of an API extension which provides the data chunks of the currently played audio?

The GetSpectrumData only provides the FFT from the BASS library as far as I was able to explore.

It turned out other algorithms (https://getmusicbee.com/forum/index.php?topic=39765.msg224003#msg224003) can be used for deriving the spectrum data, which provide better frequence consistency among the spectrum.
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on June 10, 2024, 03:11:25 AM
pretty much the most necessary feature request for a new API function for analysis-oriented visualizations (oscilloscope, peak/RMS meters, etc.) as some of audio analysis algorithms (including certain spectral analysis algorithms like IIR filter bank and even non-power of two FFTs like 4800 samples long FFT) do require raw audio data (which is an array of floating-point numbers representing a short chunk of raw audio data before being put into FFT) in order to function properly

BTW unless the FFT data MusicBee currently have is complex-valued (which can have negative values as the magnitude is a hypotenuse of real and imaginary parts of FFT data, which can't have negative values), it is not possible to properly implement something like Brown-Puckette CQT/VQT (which uses a frequency kernel derived directly in frequency-domain to sharpen time-resolution at higher frequencies) and reassigned FFT (which I think needs complex-valued FFT) into CoolEdit Nostalgia visualizer
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on July 04, 2024, 05:20:58 AM
Don't forget that IIR filter bank spectrum analyzer do require delta timing thing (to ensure samples don't overlap or miss) in-addition to an API to get floating-point sample data, since the display framerate is indeed variable (at least for realtime visualizations), so for 60fps display framerate and 48kHz audio samplerate, you need to get approximately 800 samples, and for 30fps, you'll need something like 1600 samples but even a one sample off the required length can cause clicks/pop artifacts to pop up on the filter bank analyzer even if you can't hear these since the visualization doesn't touch the actual audio data (besides reading sample data for audio analysis)
Title: Re: Getting the raw audio samples data
Post by: kamen on July 26, 2024, 03:35:24 PM
For those interested in using the raw audio samples, I can let you know that using a winamp dsp plugin is a working soultion.
There are several technical limitations such as:  buffer size (which depends on the audio device) and maximal frequency and bit depth (which are limited to 44100khz, 16bit).
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on July 28, 2024, 09:06:44 PM
For those interested in using the raw audio samples, I can let you know that using a winamp dsp plugin is a working soultion.
There are several technical limitations such as:  buffer size (which depends on the audio device) and maximal frequency and bit depth (which are limited to 44100khz, 16bit).
Fair enough, it is a good workaround while we're waiting for Steven Mayall (the creator of MusicBee) finally adding an API function to get raw samples data (which can have any number of channels, samplerate can be anything, and it is in floating-point format unlike Winamp DSP plugins or the FLAC format) for parity with foobar2000's get_chunk_absolute() function (which is used by oscilloscope components and certain spectrum visualizations like foo_enhanced_spectrum_analyzer)
Title: Re: Getting the raw audio samples data
Post by: Steven on August 03, 2024, 11:49:45 PM
I have done a proof of concept to implement this, but before I spend more time implementing a proper solution is there anyone who is going to make use of this?
And if so, would you use C++ or C# ? (I recommend C++ for this type thing)
Your plugin would provide a function that MB directly supplies the raw PCM data to, post any DSP modifications, in real time
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on August 04, 2024, 07:03:17 PM
I have done a proof of concept to implement this, but before I spend more time implementing a proper solution is there anyone who is going to make use of this?
Not only useful for oscilloscope/vectorscope-type visualizations but also certain spectrum analyzers (especially when it uses custom FFT routine or even ditches the FFT entirely like ones that uses IIR filter bank), loudness (LUFS), and even true peak meters (basically peakmeter but sinc-interpolated to detect possible intersample peak clipping)

Obviously, plugins using this would only work on latest MB versions starting from where raw samples data acquisition for visualizations is introduced right?
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on August 25, 2024, 11:03:26 PM
True. But when you put a float32 WAVs (e.g. coming from bass boosted exports of any audio file including MP3 and other lossy sources, which contains +0dBFS peaks when decoded even before processing) while these Winamp DSPs aren't enabled, the output are limited rather than clipped/distorted right?

I'll have to dig deeper into the topic in future, but for now the float32s are transcoded into 16bits with the DSP (lesser bit depth). So is my understanding, and so is the behavior for the sample file you've prepared.
Also, both - dsp and bass - return values beyond the 0db. Whether limited in some way or not, I currently don't know. But the visual clipping to 0db comes from the CEN plugin.
Is using a Winamp DSP plugin just for working around the MB API currently not having a feature to get sample data, worth risking unintentionally "adulterating" (albeit inaudibly except on extreme bass boosted songs, assuming it is a float32 export in which there are peaks above 0dBFS line as the result of bass boosting process) the audio output by "transcoding" into int16 format (the very same reason behind the transcode warnings I've get on some WAVs when I've try converting uncompressed PCM into FLAC using foobar2000), so that the Windows' built-in audio peak limiter (that only appears when not using WASAPI exclusive output in any supported players) won't kick in because it was hardclipped to 0dB anyway?

BTW, CEN using Winamp DSP just for alternative IIR filter bank algorithm kinda reminds me of DSP Spectrum Tool plugin for Winamp using Winamp's DSP system to get around limitations of Winamp's visualization system (only 576 samples long, low bitdepth of 8-bit integer PCM data "transcoded" from higher bitdepths), though hopefully, MusicBee API adds a feature to get raw samples data, which makes the Winamp DSP as a workaround obsolete
Title: Re: Getting the raw audio samples data
Post by: Steven on August 26, 2024, 09:28:36 AM
though hopefully, MusicBee API adds a feature to get raw samples data, which makes the Winamp DSP as a workaround obsolete
all i said in the previous post above, i want someone to state that they will make use of it before I do the work to make it available
Title: Re: Getting the raw audio samples data
Post by: kamen on August 29, 2024, 08:12:33 PM
Hi Steven,

Thank your for taking the time to consider the above suggestions!

I have done a proof of concept to implement this, but before I spend more time implementing a proper solution is there anyone who is going to make use of this?
And if so, would you use C++ or C# ? (I recommend C++ for this type thing)
Your plugin would provide a function that MB directly supplies the raw PCM data to, post any DSP modifications, in real time

I can confirm that a C++ API is the way to go for such a thing, coming from my recent experience with the mentioned CEN DSP plugin. The later versions of C#/.NET also support SIMD acceleration, but cannot confirm whether it is on the same level as C++ in that regard.
Also a C++ API could help with the performance when marshaling the graphics data from the .NET to the native world (given that a plugin gets developed mainly in C++).

Quote
all i said in the previous post above, i want someone to state that they will make use of it before I do the work to make it available
I cannot say that the need for such an API is existential, but it unlocks the possibility for a bit more quality for the plugins in the future. Again from my experience with the CEN plugin, this would mean more suitable Fourier transformations for the specific purpose - spectrograms, vu-meters, etc. which brings a bit more quality to the visualizations and expands the options for diverse algorithms.

In short, I'll be happy to use your API, or at least to test it at this early stage.


Title: Re: Getting the raw audio samples data
Post by: Steven on August 31, 2024, 10:39:22 AM
get the latest v3.6 update and use this updated MusicBeeBass.dll
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file

In your C++ plugin, export this function name "GetPCMRawData"
Code
__declspec(dllexport) void GetPCMRawData(float*, int);

// called in real time with a copy of current playing stream data, but MB calls this function in a separate thread to protect MB from potential interference from the plugin.
void GetPCMRawData(float* data, int length) {
}
MB will look for that function and use it to send data to it
Title: Re: Getting the raw audio samples data
Post by: kamen on September 04, 2024, 08:28:29 PM
Thank you Steven!

I managed to execute some initial tests and the GetPCMRawData gets triggered as desired during playback.
An exception when it doesn't get triggered however is when the option "on startup -> resume playback" is activated.

I'll report back when I test the whole dynamics of my plugin and the actual data values.

For my tests I used MB3.6 Patched from 2.09.2024 with the updated MusicBeeBass.dll.
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on September 06, 2024, 05:07:11 AM
I'll report back when I test the whole dynamics of my plugin and the actual data values.
BTW,  are "proper" Mid/Side (M/S) mode only possible with new API to get raw samples data, or it is already done with built-in function to get spectrum data?
Title: Re: Getting the raw audio samples data
Post by: kamen on September 06, 2024, 10:21:18 AM
It seems that my post from two days ago is somehow lost during the forum down-time, so I'll try to reproduce it again:

@Steven:
To test the GetPCMRawData, I used a 1khz test signal at 44.1khz sampling rate and compared the results with the dsp api output.
So the results are:
-a couple chunks with normal values
-a couple chunks with too high values (100 to 2000)
-one or two chunks with zeros
The whole pattern repeats for the duration of the audio file.

The test was done with WSAPI shared output, but there is also a corruption pattern with ASIO too.

@TF3RDL: The comparison between the APIs for a specific algorithm has to come at a later stage.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 06, 2024, 10:47:03 AM
the link has been updated
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
Title: Re: Getting the raw audio samples data
Post by: kamen on September 07, 2024, 10:39:41 AM
the link has been updated
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file

Very good results!

The data is now correct and the function triggering on startup is now fixed.
Compared to the DSP, the Raw API is visibly a lot more responsive and immediate - truly real-time!

I have a couple more issues, that I noticed:
1) disabling the C++ plugin crashes/closes MB
2) changing the audio output (in preferences) stops the triggering of GetPCMRawData.
3) About the quality of the data:
- It looks to be sampled at 44.1khz and upsampled to the audio file sample rate, for audio files up to 88.2khz. For audio files above 88.2khz, it remains the at 88.2khz, which is still upsampled 44.1khz.
- For my tests with the frequency band algorithm from TF3RDL, I get proper spectrum information only up to 22.05khz, which is equal to the DSP api and corresponds to 44.1 sampling rate.
- The MB GetSpectrumData function on the other hand delivers spectrum that corresponds to the actual file sampling rate. Is there a way to get comparable behavior from GetPCMRawData?

Thank your for your efforts.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 08, 2024, 09:31:07 AM
for the first 2 issues, the link has been updated
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
and also
https://getmusicbee.com/patches/MusicBee36_Patched.zip

I dont get your statements about resampling. MB is just intercepting the DSP chain from bass after it has decoded the raw data and before the data is sent to the output device. Unless you have the "resample to" option ticked in the player preferences, I dont see why bass would resample anything ie. the data you receive should be the sample rate from the source file. However there was a bug in MusicBeeBass.dll now fixed which i guess might somehow have affected what you  were seeing.
Title: Re: Getting the raw audio samples data
Post by: sveakul on September 08, 2024, 08:56:21 PM
If he's mistakenly using Wasapi-shared he would end up with output resampled by Windows to whatever the Windows Mixer was set to, no matter what he set/didn't set in MusicBee, correct?  Wasapi-exclusive needs to be used.

Also:  the updated MusicBeeBass.dll was not contained in the MusicBee36_Patched.zip in the same post--does this mean others should hold off on replacing the DLL yet?
Title: Re: Getting the raw audio samples data
Post by: kamen on September 09, 2024, 10:21:02 AM
for the first 2 issues, the link has been updated
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
and also
https://getmusicbee.com/patches/MusicBee36_Patched.zip

I dont get your statements about resampling. MB is just intercepting the DSP chain from bass after it has decoded the raw data and before the data is sent to the output device. Unless you have the "resample to" option ticked in the player preferences, I dont see why bass would resample anything ie. the data you receive should be the sample rate from the source file. However there was a bug in MusicBeeBass.dll now fixed which i guess might somehow have affected what you  were seeing.
Your statement that bass doesn't do any additional resampling is enough for me at the moment. I'll try to run standard FFT to verify that, but it will take some time. Up to now I only compared the sizes of the data streams per second and used a frequency band transformation to check the spectrum structure visually. The latter might not be the ultimate proof for resampling or cut off frequencies, that I am suspecting, but here is how it looks like for a 48khz audio file:
(https://i.imgur.com/PLndbgd.png)


Also my report on the three issues in your latest version:
1)Disabling/enabling the c++ plugin is fixed.
2)Changing the device output also works, but there is some regress. If I use the player next/previous track controls or select a song other than the played on startup, the RawData function never gets called again... unless I change the output settings!
3) Now the DSP stream is no longer fixed at 44.1khz, but equals the raw data stream size. Won't this break the functioning of some older winamp plugins?
Title: Re: Getting the raw audio samples data
Post by: kamen on September 09, 2024, 10:26:41 AM
If he's mistakenly using Wasapi-shared he would end up with output resampled by Windows to whatever the Windows Mixer was set to, no matter what he set/didn't set in MusicBee, correct?  Wasapi-exclusive needs to be used.

Also:  the updated MusicBeeBass.dll was not contained in the MusicBee36_Patched.zip in the same post--does this mean others should hold off on replacing the DLL yet?
We are comparing the audio data before being passed to the output driver/device. I mixed up WSAPI and ASIO during the testing, because it changes the data chunk size on each RawData or DSP function call.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 10, 2024, 10:26:18 AM
2)Changing the device output also works, but there is some regress. If I use the player next/previous track controls or select a song other than the played on startup, the RawData function never gets called again... unless I change the output settings!
this should work
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
Title: Re: Getting the raw audio samples data
Post by: kamen on September 11, 2024, 02:29:14 PM
2)Changing the device output also works, but there is some regress. If I use the player next/previous track controls or select a song other than the played on startup, the RawData function never gets called again... unless I change the output settings!
this should work
https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
Yes, it works!
This allows me to test it for a while and fix my own plugin issues around it.
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on September 11, 2024, 02:52:59 PM
This allows me to test it for a while and fix my own plugin issues around it.
Good, though it is not complete without replacing the built-in FFT method with a custom FFT routine that permit non-power of two sample lengths and even makes Mid/Side representations possible (if built-in method of getting spectrum data doesn't support Mid/Side mode)

Other forms of visualizations like actual oscilloscope and vectorscope should also be possible with new API

BTW, have you extensively compared your filter bank implementation within your plugin with my own implementation (https://codepen.io/TF3RDL/pen/MWLzPoO) for a completely different platform? Like testing these two with test tones, white and pink noise to make sure they matched up with eachother and obviously, there shouldn't be any missing or overlapping samples, otherwise it would lead to "wrong" results (as expected on my own spectrum analyzer project when switching from AudioWorklet-based sample acquisition to AnalyserNode-based one)
Title: Re: Getting the raw audio samples data
Post by: kamen on September 21, 2024, 09:01:26 PM
I was able to test a bit more, including generation of a FFT spectrogram. The spectrogram results from the raw API and DSP are similar to the GetSpectrum function, which is a positive confirmation for the qualities of the streams.

During the testing I noticed two more small bugs:
4) A DSP plugin does not work anymore after disabling/enabling in "Equalizer/DSP Settings" using the checkbox. To work again I should disable/enable the menu entry "Control->DSP Effects" or restart MB. This seems to be a 3.6 bug, 3.5 was working correctly with that.
5) When an automatic change between two tracks in a playlist with different sample rates occurs, then the DSP and RAW streams remain at the sample rate of the first track. It works correctly again if I manually change the track.

Both tested with the most recent patched version.
Title: Re: Getting the raw audio samples data
Post by: sveakul on September 21, 2024, 09:31:47 PM
4) A DSP plugin does not work anymore after disabling/enabling in "Equalizer/DSP Settings" using the checkbox. To work again I should disable/enable the menu entry "Control->DSP Effects" or restart MB. This seems to be a 3.6 bug, 3.5 was working correctly with that
I noticed this too just a day ago testing settings for possible effects on VU meters--unchecking the VST in the settings box in real-time does disable its effect on the audio, but re-checking it does not re-enable it until MB is restarted.  Did not happen with 3.5, which would re-enable live as soon as the plugin was re-checked.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 23, 2024, 09:49:01 AM
During the testing I noticed two more small bugs:
4) A DSP plugin does not work anymore after disabling/enabling in "Equalizer/DSP Settings" using the checkbox. To work again I should disable/enable the menu entry "Control->DSP Effects" or restart MB. This seems to be a 3.6 bug, 3.5 was working correctly with that.
5) When an automatic change between two tracks in a playlist with different sample rates occurs, then the DSP and RAW streams remain at the sample rate of the first track. It works correctly again if I manually change the track.
should work now:
https://getmusicbee.com/patches/MusicBee36_Patched.zip
Title: Re: Getting the raw audio samples data
Post by: kamen on September 23, 2024, 12:01:53 PM
Yes, both are fixed now.
Thank you!
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 27, 2024, 05:47:14 AM
This data seems to be post REPLAYGAIN_TRACK_GAIN and RVAD tag values, is that intended?

I thought it was supposed to be raw data before any alterations.

edit: actually that makes sense, nevermind.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 27, 2024, 09:00:03 AM
it is supposed to be before any volume adjustment. If you believe its not the case, I can spend some time testing it to confirm
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 27, 2024, 11:55:51 AM
Disclaimer - I had a few drinks with dinner so the results could be questionable....

But from my testing it seems that both -
GetPCMRawData
and
NowPlaying_GetPeak

Both return values post track tags AND player EQ settings.

I haven't tested with any DSP plugins.

I've got an option setup to switch between the sources of data and they both display similar results when I adjust the Replay_track_gain tags or player equalizer settings.

Just to make it clear I'm not mixing things up and looking at the same source of data.

When I set the pre-amp in the EQ settings to +3db and run a test file at zero level I consistently get the following values -
GetPCMRawData - 1.412495
NowPlaying_GetPeak - 1.412538

If I disable EQ and set a +3db REPLAY_GAIN_TRACK tag I consistently get -
GetPCMRawData - 1.412494 (0.000001 difference)
NowPlaying_GetPeak - 1.412538

Setting both  +3db EQ pre-amp gain and +3db replay gain tag adds together as expected and returns a +6db(1.99) result from both data sources.

edit: This seems to be a consistent result with WASAPI Exclusive and WASAPI Shared.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 28, 2024, 06:29:03 AM
it looks like volume and equaliser (which use BassFX) ordering are independent and ahead of the ordering for DSP callbacks (which is what GetPCMRawData is using). Its also post any user volume slider adjustment.
Not sure if there is anything i can do about that

I guess MB could edit the samples and normalise to 100% volume. However. that still still be post an active equaliser but pre all other dsp applied
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 28, 2024, 07:46:38 AM
I don't know if anyone else needs the pre vs post levels and if they would use it.

For me it's just so I can make a needle point to a different place which I can make happen with adjustments.

It seems both sources are pre DSP from some testing I did with the LoudMax DSP plugin, I set it to max value and it doesn't seem to adjust the values at all.

So to get a pre everything value I would need to adjust for the EQ preamp, Replaygain_Gain_Track tag and RDAV tag.

I already have the the Replaygain tag sorted, I don't know how necessary the RDAV tag is really.... so it's mainly the EQ preamp value.

The other issue no one else has seemed to notice is this means the VUmeter hasn't been accounting for any DSP plugins and I actually can't provide a true post value unless I go back to querying the audio device directly. But that gets broken by WASAPI exclusive mode and the library seemed to cause issues on some peoples machines so I'm not doing that.

For the sake of simplicity, if I was able to access the EQ preamp value I think that would satisfy most people in terms of Pre values. I don't know if the rest is worth messing around with. It's just more work for something that isn't going to be 100% accurate either way.
Title: Re: Getting the raw audio samples data
Post by: hiccup on September 28, 2024, 08:08:20 AM
I don't know if anyone else needs the pre vs post levels and if they would use it.
The sole reason why I raised this matter was that with ReplayGain active, the needle only travels a small part of the scale, not making use of the available space at all.
So it's never (close to) accurate, and it makes the loudness always seem soft.

So when I thought about that, I assumed it would be a good and reasonably simple solution to have the plugin using the raw audio data, thinking that would be easily available.
I was also guessing that there would be users that would like to see the plugin using the post-processed audio. (pre-amp, VST, ReplayGain, volume slider, whatever)
So that's why I suggested a pre vs. post option.

But now this seems to be very hard to accomplish:
The only thing I personally care about (a lot) is that ReplayGain values are ignored.
I do not care (much) about being able to use post-processed audio.
Title: Re: Getting the raw audio samples data
Post by: Bee-liever on September 28, 2024, 09:14:28 AM
The only thing I personally care about (a lot) is that ReplayGain values are ignored.

Or compensated for.

The only DSP's I use are not effecting the VUMeter readings (I think they are processed further down the chain anyway)
Title: Re: Getting the raw audio samples data
Post by: kamen on September 28, 2024, 10:49:43 AM
According to my measurements - both DSP and RawAPI samples are with replay gain applied (if enabled in MB of course).
Title: Re: Getting the raw audio samples data
Post by: kamen on September 28, 2024, 11:10:54 AM
Its also post any user volume slider adjustment.
Both DSP and RawAPI samples are disregarding the volume slider adjustments. Only replaygain, the preamp and equalizer are applied to both.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 28, 2024, 11:49:32 AM
Its also post any user volume slider adjustment.
Both DSP and RawAPI samples are disregarding the volume slider adjustments. Only replaygain, the preamp and equalizer are applied to both.
for wasapi exclusive it will be applying the volume slider
if its useful i am happy to add an api call to get/notify the volume adjustment being applied to the current stream
Title: Re: Getting the raw audio samples data
Post by: kamen on September 28, 2024, 01:29:24 PM
for wasapi exclusive it will be applying the volume slider
if its useful i am happy to add an api call to get/notify the volume adjustment being applied to the current stream

I won't go that far to compensate the samples for just one output device type, but I like the idea for additional stream properties information (similar to the winamp dsp api).
Together with the volume information, the actual sample rate can also be very useful (it may differ from the file sample rate information - having a dsd file, or using the "resample to" options). Number of channels too (look at the "upmix stereo to 5.1") - it can deliver 2 or 5. Bit depth - if available...
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 29, 2024, 01:14:02 AM
if its useful i am happy to add an api call to get/notify the volume adjustment being applied to the current stream

If that included the EQ pre-amp adjustment that would be useful.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 29, 2024, 07:56:16 AM
https://getmusicbee.com/patches/MusicBee36_Patched.zip

If you define a function named GetStreamInformation, MB will call it when a track starts playing, passing various information about the playing stream and volume settings
Code
    [StructLayout(LayoutKind.Sequential)]
    public struct StreamInfo
    {
        public int OutputApi;
        public int ChannelCount;
        public int SampleRate;
        public long Length;
        public double Volume;
        public double PreAmp;
        public double ReplayGain;
    }

    public void GetStreamInformation(IntPtr ptr)
    {
        StreamInfo info = (StreamInfo)Marshal.PtrToStructure(ptr, typeof(StreamInfo));
    }
use the Volume field if you want to adjust when OutputApi == WasapiExclusive

Code
OutputApi has these values:
        WasapiShared = 1
        Asio = 2
        WasapiExclusive = 3

in C++ export a function
Code
__declspec(dllexport) void GetStreamInformation(StreamInfo*);

struct StreamInfo
{
int OutputApi;
int ChannelCount;
int SampleRate;
long long Length;
double Volume;
double PreAmp;
double ReplayGain;
};


void GetStreamInformation(StreamInfo* info)
{
}
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 29, 2024, 11:50:05 AM
Excellent. Thanks. I'll have a play around with that tomorrow.
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on September 29, 2024, 12:39:52 PM
Both DSP and RawAPI samples are disregarding the volume slider adjustments. Only replaygain, the preamp and equalizer are applied to both.
On the unrelated note, visualization data (both waveform and spectrum) on foobar2000 are gathered after all DSP effects but before the volume slider

And that volume slider in foobar2000 takes effect immediately but changing the settings of any DSP(s) like "Equalizer" takes time to actually hear it, with a delay proportional to the output buffer size
Title: Re: Getting the raw audio samples data
Post by: kamen on September 29, 2024, 11:19:40 PM
Code
struct StreamInfo
{
        int OutputApi;
int ChannelCount;
int SampleRate;
long long Length;
double Volume;
double PreAmp;
double ReplayGain;
};

I tested the c++ and the c# versions specifically for sample rate and number of channels.

1)The DSP api always contains correct information for sample rate and number of channels. The new callback does not, especially when "upmix channels" and "resample" options are used. Please, pass the same information for those two from the DSP to the RawAPI too.
2)The callback function does not get triggered when "resume playback on start" is activated.


The rest of the properties seem to work well, but did not test them as much.
Just a question: What does Length contain? Frames count?
Title: Re: Getting the raw audio samples data
Post by: BoringName on September 30, 2024, 04:54:53 AM
Seems to be working ok for me.

I haven't played around with OutputApi and Volume yet but the ReplayGain and PreAmp are just what I needed. It also takes the RVAD tag into account so that's a plus. Thanks.
Title: Re: Getting the raw audio samples data
Post by: Steven on September 30, 2024, 09:51:20 AM
https://getmusicbee.com/patches/MusicBee36_Patched.zip

i have changed the format for c# and c++ to include outputsamplerate, outputchannelcount and other fields. Not tested but should work

Code
[StructLayout(LayoutKind.Sequential)]
public struct SoundStreamInfo
{
    public int OutputApi;
    public int OutputChannelCount;
    public int OutputSampleRate;
    public int SourceChannelCount;
    public int SourceSampleRate;
    public int SourceDsdRate;
    public int SourceBitsPerSample;
    public long Length;
    public double Volume;
    public double PreAmp;
    public double ReplayGain;
}

Length is the decoded number of bytes for the entire file. For MP3 files it is a near estimate
Title: Re: Getting the raw audio samples data
Post by: Steven on September 30, 2024, 12:00:34 PM
also could you use this MusicBeeBass.dll

https://www.mediafire.com/file/sl0k311vrbbs66j/MusicBeeBass.dll/file
Title: Re: Getting the raw audio samples data
Post by: kamen on September 30, 2024, 02:27:09 PM
I liked the split output/source sample rate and channel count, but even with the new bass dll, I have some problems:

Code
public struct SoundStreamInfo
{
    public int OutputApi;   // always 0, previously worked well
    public int OutputChannelCount;  // always 0
    public int OutputSampleRate;  // always 0
    public int SourceChannelCount; // works very well
    public int SourceSampleRate; // works very well
    public int SourceDsdRate;  // works very well
    public int SourceBitsPerSample; // works very well

// the rest is unchanged -> works
    public long Length;
    public double Volume;
    public double PreAmp;
    public double ReplayGain;
}

The callback on startup is also missing (if something has changed there).
Title: Re: Getting the raw audio samples data
Post by: BoringName on October 01, 2024, 05:59:51 AM
I liked the split output/source sample rate and channel count, but even with the new bass dll, I have some problems:

Just confirming I'm getting the same results as kamen.
Title: Re: Getting the raw audio samples data
Post by: Steven on October 01, 2024, 10:11:01 AM
tested with the C# interface and should work now for both
https://getmusicbee.com/patches/MusicBee36_Patched.zip
Title: Re: Getting the raw audio samples data
Post by: BoringName on October 01, 2024, 12:05:08 PM
I haven't checked all the settings but OutputApi, OutputChannelCount, Volume, PreAmp and ReplayGain are working for me.
Title: Re: Getting the raw audio samples data
Post by: kamen on October 01, 2024, 02:40:18 PM
tested with the C# interface and should work now for both
https://getmusicbee.com/patches/MusicBee36_Patched.zip
GetStreamInformation does not get called at all for c++ and c#.

I'm perplexed as BoringName says it works on his setup.
Title: Re: Getting the raw audio samples data
Post by: Steven on October 01, 2024, 09:30:54 PM
GetStreamInformation does not get called at all for c++ and c#.
its also working for me. Is your plugin enabled? I changed it so an explicit check is done before calling the function

edit:
actually it wont get called if you dont also have GetPCMRawData exported. I will fix that tonight
Title: Re: Getting the raw audio samples data
Post by: Steven on October 02, 2024, 09:30:47 AM
the above is fixed now
Title: Re: Getting the raw audio samples data
Post by: Steven on October 02, 2024, 10:27:33 AM
you dont have to update the streaminfo structure definition but i have added one more field at the end:
public bool LogarithmicVolume;
if you are adjusting sample data for volume for the wasapi exclusive volume slider, and LogarithmicVolume = true then you should divide the Volume value by Math.Pow(10, ((PlayerSettings.Volume - 1) * 40) / 20)

i will not add the field and just adjust the Volume value instead
Title: Re: Getting the raw audio samples data
Post by: kamen on October 02, 2024, 11:34:45 AM
actually it wont get called if you dont also have GetPCMRawData exported. I will fix that tonight
Your guess and the following fix did the trick. I'm very much happy with how it works!

I want to state two lesser issues, without pushing for a fix. It may be useful for the stabilization of the api.
1) If two plugins (one c++ (background) and one c# (with visible panel)) are implementing GetPCMRawData, then GetPCMRawData for the c++ one does not get called. I have a c++ bridge plugin, so I found that by accident.
2) You close the player while playing a song with this option selected (https://i.imgur.com/z1XR2hF.png). After starting the player again it continues to play, but GetPCMRawData and GetStreamInformation does not get called, unless another song is selected.
Title: Re: Getting the raw audio samples data
Post by: Steven on October 03, 2024, 11:49:39 AM
both should be fixed now, updated musicbeebass.dll is included in this zip
https://getmusicbee.com/patches/MusicBee36_Patched.zip

the first required significant changes which I have tested
Title: Re: Getting the raw audio samples data
Post by: kamen on October 03, 2024, 01:06:17 PM
both should be fixed now, updated musicbeebass.dll is included in this zip
https://getmusicbee.com/patches/MusicBee36_Patched.zip

the first required significant changes which I have tested


It works very good! I think there is no regression, it just got better!

1) It is solid. No problems at all.
2) After finishing the startup song, it posts the GetStreamInformation for the next song. I'm good with that.

Thanks for including the bass dll into the zip.
Title: Re: Getting the raw audio samples data
Post by: BoringName on October 04, 2024, 03:19:43 AM
I'm having an issue with the portable version. streamInfo.PreAmp is coming through as zero regardless of what the EQ PreAmp is set to. I'm using 3.6.9041 on both versions and they both have the new MusicBeeBass.dll with the same version of my plugin.

Installed works, portable is coming through as zero. I can't see anything I've done that could cause that, It's not just my machine, another user is having the same issue.

ReplayGain and OutputChannelCount seem ok. I haven't checked the other outputs.

This is the function I'm using and I just get the values directly from streamInfo.
Code
public void GetStreamInformation(IntPtr ptr)
        {
            streamInfo = (SoundStreamInfo)Marshal.PtrToStructure(ptr, typeof(SoundStreamInfo));
           
        }
Title: Re: Getting the raw audio samples data
Post by: Steven on October 04, 2024, 04:14:25 AM
preamp is only applied if the equaliser is enabled
Title: Re: Getting the raw audio samples data
Post by: BoringName on October 04, 2024, 05:02:45 AM
preamp is only applied if the equaliser is enabled

That would be it. And I can check if the equaliser is enabled in the api so all good. Thanks.

edit: I'd modified the preamp value but completely missed the "enable equaliser" at the top.
Title: Re: Getting the raw audio samples data
Post by: kamen on October 06, 2024, 08:00:05 PM
Anomaly just noticed:  when using RawAPI 4K, occasionally there is a "blip" of small spectrum at the extreme right end of the kHz scale which seems unrelated to the source freqencies, i.e. not just an occasional very high frequency actually from the source.  This disappears when changing to MusicBee Native Fourier.  Using Linear for scale and interpolation, Normal dB, Time 75ms/60fps  Two shots from bars and regular:
(https://i.imgur.com/m1HESk6.png) (https://i.imgur.com/iPvrh3l.png)
I think you've found something important.

To test it further I set the resemple setting of the MB output to 96khz of a normal 48khz audio file. Then I observed the same artifacts in the zone above 24khz (where there isn't any audio). The artifacts are not present on the DSP source, although the same algorithm pipeline is used for both.

Here are the screenshots (first RAW API, then DSP):
(https://i.imgur.com/tySV38W.png)
(https://i.imgur.com/BJFyri2.png)

It seems to me that the RAW API can have some kind of synchronization problem. But I'm speculating here. Maybe Steven has more to say on that.
Title: Re: Getting the raw audio samples data
Post by: Steven on October 07, 2024, 04:09:41 AM
MB just passes through the data that bass sends it. However there is some inter-thread interaction so as a temporary testing thing, this version passes the data directly from the bass callback and not via a separate thread. So if it still has unexpected behavior then its not MB

musicbeebass.dll test file:
https://mega.nz/file/00dkTSTB#6VpGC9YPu2JGKhUhxH_71xefu_7BvMR3EhXoyKC2gT8
Title: Re: Getting the raw audio samples data
Post by: kamen on October 07, 2024, 01:44:55 PM
Good idea. I couldn't use the test bass, because it crashes for some reason, when I click play.

Through debugging, I've isolated the problem to a floating point rounding issue, which presents very small fractional numbers as 0.
For the silent signal part of the FFT spectrogram the values for rawapi are about e-10 and some occasional zeros, where for the the DSP e-5 and no zeros (due to the higher silence level).
Those zeros then convert into the decibel scale improperly as blips.

So it is in the end a conversion error on my side.
Should it have been a threading problem, some artifacts should be visible also elsewhere on the spectrum (not only the silent part).
Title: Re: Getting the raw audio samples data
Post by: sveakul on October 12, 2024, 08:59:58 AM
Good idea. I couldn't use the test bass, because it crashes for some reason, when I click play.

Through debugging, I've isolated the problem to a floating point rounding issue, which presents very small fractional numbers as 0.
For the silent signal part of the FFT spectrogram the values for rawapi are about e-10 and some occasional zeros, where for the the DSP e-5 and no zeros (due to the higher silence level).
Those zeros then convert into the decibel scale improperly as blips.

So it is in the end a conversion error on my side.
Should it have been a threading problem, some artifacts should be visible also elsewhere on the spectrum (not only the silent part).

kamen, will you be releasing an incremental update to CoolEdit Nostalgia 5 soon, with those fixes to the RawAPI Bridge mode in place?  The artifacts the error produces in the spectrum, albeit slight, get distracting once you know they are there!
Title: Re: Getting the raw audio samples data
Post by: kamen on October 12, 2024, 10:21:34 AM
kamen, will you be releasing an incremental update to CoolEdit Nostalgia 5 soon, with those fixes to the RawAPI Bridge mode in place?  The artifacts the error produces in the spectrum, albeit slight, get distracting once you know they are there!
Yes, I want to make a small update together with some other things I'm currently testing. I'll write about it on the plugin's thread when ready.
Title: Re: Getting the raw audio samples data
Post by: sveakul on October 12, 2024, 08:59:17 PM
Great, thanks!
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on October 24, 2024, 01:02:43 AM
BTW, the RawAPI thing is not complete without an oscilloscope (https://codepen.io/TF3RDL/pen/gOVXaxm) or even a realtime LUFS meter (https://codepen.io/TF3RDL/pen/gONWJby) as visualization plugin for MB
Title: Re: Getting the raw audio samples data
Post by: Mayibongwe on October 24, 2024, 06:37:20 PM
BTW, the RawAPI thing is not complete without an oscilloscope or even a realtime LUFS meter as visualization plugin for MB
Looks cool. But these features, are they something that you wish to incorporate into a new MusicBee plugin that you are currently developing?
If so, what specific info are you looking to get from the MB API that you cannot currently access?

or are they something that you'd like to see in one of the existing MB plugins (I'm guessing Kamen and BoringName's add-ons)?
If the latter, then you'd first have to check with those developers to see if it's something they are interested in building to their plugins.

If they wouldn't be interested, I don't think it'd be reasonable to ask Steven to spend his limited time enhancing API calls that no user has plans to make use of.
Title: Re: Getting the raw audio samples data
Post by: TF3RDL on October 25, 2024, 04:37:43 AM
Looks cool. But these features, are they something that you wish to incorporate into a new MusicBee plugin that you are currently developing?
If so, what specific info are you looking to get from the MB API that you cannot currently access?
An API to get raw sample data with arbitrary length should be enough to implement almost anything other than oscilloscope visualization, something like an LUFS meter

or are they something that you'd like to see in one of the existing MB plugins (I'm guessing Kamen and BoringName's add-ons)?
If the latter, then you'd first have to check with those developers to see if it's something they are interested in building to their plugins.
Perhaps either kamen or BoringName (or even someone else who interested in developing plugins for MB and have some needed expertise on DSP especially the LUFS metering) could implement either the realtime LUFS meter (with a reasonable amount of accuracy and compliance with ITU-R BS.1770 standard), the oscilloscope visualization (of course with multichannel support to visualize waveforms of surround sound), or even both

If they wouldn't be interested, I don't think it'd be reasonable to ask Steven to spend his limited time enhancing API calls that no user has plans to make use of.
Yeah, what I meant is that an API to get raw samples data is more than enough and adding a realtime LUFS metering capabilities should be left to plugin developers rather than an API function to fetch LUFS of currently-playing song, which isn't needed as it can be done just by using the waveform data and transform into something that makes sense
Title: Re: Getting the raw audio samples data
Post by: kamen on October 31, 2024, 04:29:40 PM
For the next update of CEN there will be a simple waveform viewer integrated.

@Steven

While testing various things I came to two issues that relate to the raw api, which are worth mentioning:
1) The raw api skips chunks/calls when the output device uses chunks less than 512 samples ( roughly 20% of the chunks are missing). The DSP however works well, and the sound isn't affected. I used FlexASIO for the tests, as it has configurable latency.
2) The time delivered by Player_GetPosition() seems to be very inaccurate compared to the time interval between the chunks (sometimes showing the same time for whole series of chunks). It would be nice if it can be improved a bit.
Title: Re: Getting the raw audio samples data
Post by: Steven on November 02, 2024, 04:37:14 AM
this test version directly calls the sample data api without using a background thread
https://www.mediafire.com/file/g8hfzwfvi40e0nn/MusicBeeBass.zip/file

note that if the processing on side is too slow it will cause playback to stutter and if you modify the values in the data array it will change what is sent to the output device
Title: Re: Getting the raw audio samples data
Post by: kamen on November 02, 2024, 05:04:35 PM
note that if the processing on side is too slow it will cause playback to stutter and if you modify the values in the data array it will change what is sent to the output device
Thank you for that. It turns out the processing time of my callback + any time jitter (due to MB thread, windows, etc.) is about 5-6ms, which obviously becomes critical to maintain at below 512 samples.

I tested that by adding extra sleep time into the callback.Your test MusicBeeBass is only working for C#. It crashes on a C++ plugin, even with empty callback function, so I wasn't able to test it directly on my code.
Title: Re: Getting the raw audio samples data
Post by: Steven on November 02, 2024, 10:56:07 PM
I am uncertain how the C++ plugin would ever have worked based on what i told you previously. GetPCMRawData needs to be defined

Code
	__declspec(dllexport) void (__stdcall GetPCMRawData(float*, int));
void __stdcall GetPCMRawData(float* data, int length)
Title: Re: Getting the raw audio samples data
Post by: kamen on November 03, 2024, 05:53:47 PM
With __stdcall the function does not get called at all and for me it makes sense.

All functions that MB calls from the plugin are __cdecl - such as SaveSettings, Close, Uninstall... GetPCMRawData too. (callbacks)
All functions that the plugin calls from MB are __stdcall - such as Player_GetPosition, Player_GetVolume, etc. (the api interface functions)
Title: Re: Getting the raw audio samples data
Post by: Steven on November 04, 2024, 09:54:03 AM
With __stdcall the function does not get called at all and for me it makes sense.

All functions that MB calls from the plugin are __cdecl - such as SaveSettings, Close, Uninstall... GetPCMRawData too. (callbacks)
All functions that the plugin calls from MB are __stdcall - such as Player_GetPosition, Player_GetVolume, etc. (the api interface functions)
its working fine here as long as you use __stdcall in the GetPCMRawData  definition
the difference with the other examples is they called from within MB itself, so the call can be decorated as a C or std function depending on whether the plugin is a .net or a c++ dll
whereas GetPCMRawData is called from within MusicBeeBass which is a C++ program and could be calling a C# version or a C++ version, so its standardised as a std function call

if you still have issues with the test files, i can have a look if you send me a zip
Title: Re: Getting the raw audio samples data
Post by: kamen on November 04, 2024, 02:19:53 PM
if you still have issues with the test files, i can have a look if you send me a zip
This is how I use it. (https://www.mediafire.com/file/1j8fnog63e2n365/test_raw_api_041124_151146.zip/file)

Basically what works for me (without the test project except for yor test MusicBeeBass.dll !) is this:
Code
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void GetPCMRawData(float*, int);
__declspec(dllexport) void GetStreamInformation(SoundStreamInfo*);
#ifdef __cplusplus
}
#endif
Title: Re: Getting the raw audio samples data
Post by: Steven on November 04, 2024, 08:06:30 PM
1) The raw api skips chunks/calls when the output device uses chunks less than 512 samples ( roughly 20% of the chunks are missing). The DSP however works well, and the sound isn't affected. I used FlexASIO for the tests, as it has configurable latency.
let me know how the test version goes. I would prefer to keep the api calls in a separate thread
Title: Re: Getting the raw audio samples data
Post by: kamen on November 04, 2024, 09:46:33 PM
if you still have issues with the test files, i can have a look if you send me a zip
This is how I use it. (https://www.mediafire.com/file/1j8fnog63e2n365/test_raw_api_041124_151146.zip/file)

Basically what works for me (without the test project except for yor test MusicBeeBass.dll !) is this:
Code
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void GetPCMRawData(float*, int);
__declspec(dllexport) void GetStreamInformation(SoundStreamInfo*);
#ifdef __cplusplus
}
#endif
Sorry, my formulation above was misleading. This (https://www.mediafire.com/file/1j8fnog63e2n365/test_raw_api_041124_151146.zip) test project crashes with your test MusicBeeBass.dll. Please advise me on how to change it.
Title: Re: Getting the raw audio samples data
Post by: Steven on November 05, 2024, 08:23:59 AM
it works if you use a module definition file, otherwise i get the same behavior you describe.
so get rid of
Code
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif
leaving
Code
	// working
__declspec(dllexport) PluginInfo* Initialise(MusicBeeApiInterface* apiInterface);
__declspec(dllexport) int Configure(void*);
__declspec(dllexport) void SaveSettings();
__declspec(dllexport) void Close(PluginCloseReason reason);
__declspec(dllexport) void Uninstall();
__declspec(dllexport) void ReceiveNotification(LPCWSTR sourceFileUrl, NotificationType type);
__declspec(dllexport) LPCWSTR* GetProviders();
__declspec(dllexport) LPCWSTR RetrieveLyrics(LPCWSTR sourceFileUrl, LPCWSTR artist, LPCWSTR trackTitle, LPCWSTR album, bool synchronisedPreferred, LPCWSTR provider);
__declspec(dllexport) LPCWSTR RetrieveArtwork(LPCWSTR sourceFileUrl, LPCWSTR albumArtist, LPCWSTR album, LPCWSTR provider);
// storage plugin only:
__declspec(dllexport) void Refresh();
__declspec(dllexport) bool IsReady();
__declspec(dllexport) void* GetIcon();
__declspec(dllexport) bool FolderExists(LPCWSTR path);
__declspec(dllexport) LPCWSTR* GetFolders(LPCWSTR path);
__declspec(dllexport) void* GetFiles(LPCWSTR path);
__declspec(dllexport) bool FileExists(LPCWSTR url);
__declspec(dllexport) void* GetFile(LPCWSTR url);
__declspec(dllexport) void* GetFileArtwork(LPCWSTR url);
__declspec(dllexport) void* GetPlaylists();
__declspec(dllexport) void* GetPlaylistFiles(LPCWSTR id);
__declspec(dllexport) void* GetStream(LPCWSTR url);
__declspec(dllexport) void* GetError();

__declspec(dllexport) void (__stdcall GetPCMRawData(float*, int));
__declspec(dllexport) void GetStreamInformation(SoundStreamInfo*);
and in the Linker options set "Module Definition File" to "TestDll.def"

and add
Code
	GetError @21
GetPCMRawData @22
Title: Re: Getting the raw audio samples data
Post by: kamen on November 05, 2024, 02:53:49 PM
Thanks a lot, it works!!
I added GetStreamInformation to the list too, but it's now clear how it's supposed to work.
Code
	GetError @21
GetPCMRawData @22
        GetStreamInformation @23

I'll write again on the findings.
Title: Re: Getting the raw audio samples data
Post by: kamen on November 05, 2024, 06:57:44 PM
1) The raw api skips chunks/calls when the output device uses chunks less than 512 samples ( roughly 20% of the chunks are missing). The DSP however works well, and the sound isn't affected. I used FlexASIO for the tests, as it has configurable latency.
let me know how the test version goes. I would prefer to keep the api calls in a separate thread

Three parameters were in the mix when I was testing:
-plugin's processing time
-sample rate
-chunks size

The worst situation is slow processing time, high audio sample rate, small chunks size.

ThreadedBass
Rarely produces audio clicks, due to slow plugin processing time (but still can with ASIO).
Looses chunks on the way, if plugin processing is too slow.
Very solid with WSAPI, where no chunk size can be changed - no sound clicks or chunk drops, plenty of plugin processing time.

TestBass
Works very well, no chunk drops with ASIO, even at 19200sample rate, 128 samples per chunk, and a reasonable processing time (about millisecond or two).
If the plugin's processing becomes slow (due to multiple plugins), you can hear sound clicks (like on a vinyl or worse).


My feeling from the whole thing is that a combination of behaviors - TestBass for ASIO and ThreadedBass for WSAPI - can be a good fit, without having to choose between the two.
And another thing: the plugin is unaware, that it looses chunks, due to other active plugins. MB can measure the processing time of all plugins and write some log entry if execution time > 1000/(sampleRate/ChunkSize) [ms]
Title: Re: Getting the raw audio samples data
Post by: Steven on November 10, 2024, 08:36:57 AM
Thanks for doing those tests and sharing the results. I think I will just keep the threaded implementation and yes, if processing in the plugin takes too long then data will get skipped as the implementation prioritizes the playback experience to the user rather than waiting for the plugin to complete its processing.
Title: Re: Getting the raw audio samples data
Post by: kamen on January 15, 2025, 10:25:50 AM
MB just passes through the data that bass sends it. However there is some inter-thread interaction so as a temporary testing thing, this version passes the data directly from the bass callback and not via a separate thread. So if it still has unexpected behavior then its not MB

musicbeebass.dll test file:
https://mega.nz/file/00dkTSTB#6VpGC9YPu2JGKhUhxH_71xefu_7BvMR3EhXoyKC2gT8

if processing in the plugin takes too long then data will get skipped as the implementation prioritizes the playback experience to the user rather than waiting for the plugin to complete its processing.

After some time working with the test-bass, it still seems to be usable and valuable when developing, because it stops the sound at the breakpoint. It also helps optimizing the speed of the samples handling on the plugin side, because it makes the delays so audible.

Maybe it will find its place in some kind of a developer mode in MusicBee.