Author Topic: BASSloud (loudness measurement)  (Read 3574 times)

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #25 on: 7 Mar '24 - 12:43 »
Ah yes, that should be using the BASS.FloatValue class because Android 10 and above blocks access to Float values. An updated BASSLOUD.JAVA file is in the package now, so please re-download to get that.

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #26 on: 25 Mar '24 - 15:51 »
Sorry in advance if I posted this in the wrong place!

I'm currently trying to implement BASSloud in a popular rhythm game, osu!. However, I'm coming across an issue. Our game uses ManagedBass for c# to use bass. To implement bassloud, I made a PR for ManagedBass to add bindings for BASSloud. Using the code from my PR (my branch), and using it to make a very rough proof of concept design (excuse the variable names) for applying loudness normalization, I use the following code in a fresh isolated console application:

Code: [Select]
// See https://aka.ms/new-console-template for more information

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Runtime.InteropServices;
using ManagedBass.Loud;
using ManagedBass;

namespace AudioNormalization
{
    public class AudioNormalization
    {
        public AudioNormalization(string file)
        {
            Bass.Free();
            Bass.Init();
            Console.WriteLine("bassloud version: " + BassLoud.Version);
            var idk = Bass.CreateStream(file, 0, 0, BassFlags.Decode | BassFlags.Float);
            Console.WriteLine("idk: " + idk);

            if (idk == 0)
            {
                Console.WriteLine("cant decode stream");
                Console.WriteLine(Bass.LastError);
                return;
            }

            var loudness = BassLoud.BASS_Loudness_Start(idk, BassFlags.BassLoudnessIntegrated, 0);
            Console.WriteLine("loudness: " + loudness);

            if (loudness == 0)
            {
                Console.WriteLine("cant start loudness measurement");
                Console.WriteLine(Bass.LastError);
            }

            int data;
            while (true)
            {
                IntPtr buffer = new IntPtr();
                data = Bass.ChannelGetData(idk, buffer,Marshal.SizeOf(buffer));

                if (data < 0) break;
            }

            Bass.StreamFree(idk);

            bool gotlevel = BassLoud.BASS_Loudness_GetLevel(loudness, BassFlags.BassLoudnessIntegrated, out float level);
            Console.WriteLine("level: " + level);
            Console.WriteLine("gotlevel: " + gotlevel);

            if (gotlevel == false)
            {
                Console.WriteLine("failed to get level");
                Console.WriteLine(Bass.LastError);
            }
        }
    }
}

internal static class Program
{
    public static void Main(string[] args)
    {
        var audioNormalization = new AudioNormalization.AudioNormalization("/Users/smallketchup/Downloads/Origami Angel - Doctor Whomst.mp3");
    }
}

However, I come across a very bizarre issue. When I try to do Bass_Loudness_Start(). The return value of the function is 0, but printing Bass.LastError returns OK. I've spent a while debugging this and can't seem to come to a solution.

To reproduce, clone my branch in the ManagedBass PR. Then pack ManagedBass and ManagedBass.Loud into a nuget package. Create a new console application using .NET 8, and overwrite Program.cs with my code. Change it to use a random mp3 file. Make sure you install ManagedBass and ManagedBass.Loud in the new console application, and make sure that you're using the local nuget packages that you made using my branch. When you run the code, it'll print out `Bass_Loudness_Start()` returning 0 (cant start loudness measurement), but will also state that `Bass_Loudness_Start()` supposedly ran without issue (OK). I'm not sure if its a problem with my implementation, or with the code in my ManagedBass PR.

Do you have any suggestions?
« Last Edit: 26 Mar '24 - 14:36 by smallketchup82 »

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #27 on: 26 Mar '24 - 12:16 »
It shouldn't be possible for BASS_Loudness_Start to fail (return 0) and the error code (from LastError) to be 0. To perhaps narrow down where the problem is, do you still get a 0 error code if you try passing an invalid handle (eg. 0) to BASS_Loudness_Start?

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #28 on: 26 Mar '24 - 12:30 »
I get the same error when I pass a 0 for the handle. The return value of the function is 0, but Bass.LastError is OK.

I'm unsure if its an improper binding (types) that is causing this, such as the code that I made in my PR to ManagedBass. Though, I made that code referencing the documentation for BASSloud. So on paper, it looks to be correct. I'm running this on MacOS with an M3, if that might be the cause of any issues?
« Last Edit: 26 Mar '24 - 12:53 by smallketchup82 »

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #29 on: 26 Mar '24 - 13:21 »
Is Bass.LastError working in general, just seemingly not with BASS_Loudness_Start? What error code do you see if you try calling other BASSloud functions with an invalid handle? Or if you pass an invalid filename to Bass.CreateStream?

Is the "BassLoud.Version" return value OK?

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #30 on: 26 Mar '24 - 13:23 »
The handle returned by CreateStream seems to be correct, judging as the return value prints as -2147483647

Bass.LastError does work. If I slightly alter the filename so that the file doesn't exist, it gives me a FileOpen error.

It seems to not work with only BASS_Loudness_Start

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #31 on: 26 Mar '24 - 14:19 »
Is Bass.LastError working properly with the other BASSloud functions, eg. do you get a BASS_ERROR_HANDLE error code when calling them with an invalid handle? Please do also check the "BassLoud.Version" return value.

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #32 on: 26 Mar '24 - 14:26 »
No. Calling BASS_Loudness_GetLevel() with a handle of 0 causes it to return False with Bass.LastError reporting it as "OK". BassLoud.Version returns 2.4.0.0. Bass.Version returns 2.4.16.7. This could be an issue with Bass.LastError but that doesn't make much sense as Bass.LastError is just a wrapper for Bass_ErrorGetCode().

This is the relevant code from ManagedBass which imports the function from bass.dll
Code: [Select]
        #region Error Code
        [DllImport(DllName)]
        static extern Errors BASS_ErrorGetCode();

        /// <summary>
        /// Gets the Error that occured on the Last Bass function that was called.
        /// </summary>
        public static Errors LastError => BASS_ErrorGetCode();
        #endregion
« Last Edit: 26 Mar '24 - 14:40 by smallketchup82 »

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #33 on: 26 Mar '24 - 14:41 »
So it seems like the error code isn't getting set by the BASSloud functions for some reason. If you first call a failing BASS function and then call a BASSloud function, do you still see the failed BASS function's error code afterwards? If so, do you have the same issue when using functions from other add-ons?

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #34 on: 26 Mar '24 - 14:45 »
That's probably it.

When I remove the return from the if statement after CreateStream, and pass a missing file to CreateStream, Bass.LastError for Bass_Loudness_Start() ends up also being FileOpen. Although, now Bass.LastError for Bass_Loudness_GetLevel() is Handle.

I don't believe we have the same issue for other addons. We use Bass.Fx, Bass.Mix, and Bass.Wasapi, in other areas and it seems to work fine.

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #35 on: 26 Mar '24 - 16:02 »
The only explanation I can think of is that BASSloud is being linked with a separate copy of libbass.dylib, and so it's setting the error code in that other copy. I see you mention using BASS 2.4.16.7. Please try upgrading BASS and all add-ons to the latest versions, as they now use an "@rpath" (rather than "@loader_path") install path on macOS. If you want to stick with an old version for some reason, it can be updated to use "@rpath" with the makefile included in the BASS 2.4.17 package (see the "macOS version" notes in BASS.TXT).

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #36 on: 26 Mar '24 - 17:28 »
Got it, I'll look into upgrading! Will report back in a bit to see if it works

smallketchup82

  • Posts: 7
Re: BASSloud (loudness measurement)
« Reply #37 on: 26 Mar '24 - 17:43 »
Updating worked! Thanks so much! The loudness handle is now returned properly.
Going to make sure everything else works now. I'll edit this again if I successfully manage to get the loudness level of the track.

Edit: Managed to get the loudness level of the track!
« Last Edit: 26 Mar '24 - 18:08 by smallketchup82 »

Ian @ un4seen

  • Administrator
  • Posts: 25786
Re: BASSloud (loudness measurement)
« Reply #38 on: 27 Mar '24 - 12:43 »
Great!