Author Topic: Getting the raw audio samples data  (Read 12976 times)

kamen

  • Jr. Member
  • **
  • Posts: 105
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.

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
Last Edit: November 04, 2024, 09:40:10 PM by kamen

Steven

  • Administrator
  • Hero Member
  • *****
  • Posts: 34974
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

kamen

  • Jr. Member
  • **
  • Posts: 105
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.

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 test project crashes with your test MusicBeeBass.dll. Please advise me on how to change it.
Last Edit: November 04, 2024, 10:07:15 PM by kamen

Steven

  • Administrator
  • Hero Member
  • *****
  • Posts: 34974
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

kamen

  • Jr. Member
  • **
  • Posts: 105
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.

kamen

  • Jr. Member
  • **
  • Posts: 105
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]

Steven

  • Administrator
  • Hero Member
  • *****
  • Posts: 34974
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.

kamen

  • Jr. Member
  • **
  • Posts: 105
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.