BASS for Universal Windows Platform (UWP)

Started by Ian @ un4seen,

Ian @ un4seen

The x86/x64 BASS.DLLs use the VC++ 2013 runtime (they can be used on both Windows 8 and 10), so you will need to add a reference to that.

If shouldn't be necesary to add a "Content" element for the Bass.Net.WinStore.dll file; adding a reference to it (via the "Browse" option) should suffice.

Unknown

Ok,

that solved the dll not found problem. But this one still remains:

Ausnahme ausgelöst: "System.Exception" in Bass.Net.WinStore.dll
Ausnahme ausgelöst: "System.TypeInitializationException" in Bass.Net.WinStore.dll
The type initializer for 'Un4seen.Bass.Bass' threw an exception.

Ian @ un4seen

Are you calling the BassNet.Registration function before you make any BASS function calls? If not, please try that.

Unknown

Ouh, so i need to register BassNet first!?

radio42

I am not sure, if the "TypeInitializationException" is caused by not calling the registration...
Normally this exception is thrown in a 64-bit application when trying to load a 32-bit bass.dll.
So could this here be a similar issue? i.e. that you are using the 'wrong' bass.dll ?

Ian @ un4seen

Quote from: UnknownOuh, so i need to register BassNet first!?

You can get a "freeware" registration key from the BASS.Net website for testing purposes.

LeTonton

Hi,
I'm totally lost.

I want use Bass.net.WinStore.

So i include my  reference Bass.Net.WinStore
I add this item on my file .csproj
<ItemGroup Condition="'$(Platform)' == 'x86'">
        <Content Include="Assets\libs\x86\Bass.Net.WinStore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Assets\libs\x86\bassmidi.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
   
  </ItemGroup>

And in my program is write
using Un4seen.Bass;

And in my code

 BassNet.Registration(my email, my code);
            Bass.BASS_Start();
            Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);

            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 1); // enable playlist processing
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PREBUF, 0); // minimize automatic pre-buffering, so we can do it (and display it) instead
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_READTIMEOUT, 30000); // 30" stream timeout
            Bass.BASS_SetConfigPtr(BASSConfig.BASS_CONFIG_NET_AGENT, IntPtr.Zero);
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_BUFFER, 5000); // 5 seconds buffer
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_BUFFER, 10000); // 10 seconds buffer

But i have exeption at the line Bass.BASS_Start(); because ddl is not found
'System.DllNotFoundException
Unable to load DLL 'bass.dll':

What should I do ?

radio42

You always need the native libs as well - as such and the exception suggests, just place your bass.bll file into your binary output folder...

LeTonton

I place my bass.dll in all folder where bass.net.winstore.dll is present, but no result.

Ian @ un4seen

Quote from: LeTontonSo i include my  reference Bass.Net.WinStore
I add this item on my file .csproj
<ItemGroup Condition="'$(Platform)' == 'x86'">
        <Content Include="Assets\libs\x86\Bass.Net.WinStore.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="Assets\libs\x86\bassmidi.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
   
  </ItemGroup>

Do you have a "Content" element for "bass.dll" too? If not, you need to add that. You don't need to have a "Content" element for "Bass.Net.WinStore.dll" though; you can just add a reference to it in your project instead.

Jfarro

Thanks for this library! I'm just getting up and running with it, and the documentation has been amazing.

Some quick notes for others that use this for windows store (It's in the thread, I just missed it)
1) If you're making a Universal Windows App, add the Bass.net.winstore in references
2) Then add the appropriate bass.net.dll....you should do this in your project file.  If you're testing and getting up and running...you can just add the dll to the project as 'content' and ensure it is set to 'copy if newer'
3) If you use Windows phone, add the win10 arm reference and the VS2015 reference. Otherwise add the win8 reference and appropriate architecture bass.net reference
4) If you get a badimageformat exception...then you mixed an x86 build with an x64 build...redo step 3
5) If you get a 'bass.net' can't be found error...check your output / debug folders and look for it..if it's there...ensure you've add the vs 2013/2015 reference
6) If you crash right away, ensure you're calling: Un4seen.Bass.BassNet.Registration with your email and registration info.  The help says it'll throw a splashscreen, but if you don't have that line you'll get a Typeinitialization exception.

With all of that done, I was on my way fairly quickly using the offline help and tutorials

Jfarro

Two questions as I work through this:

1) I'm not seeing the Bass.Misc namespace for windows store...I was hoping to play with the Visual object and such...any chance we could get that? or is it there and I'm missing it?

2) I'm having problems getting midis to play on win10 with Bass. I loaded up xmplayer and also didn't have audio till I loaded a soundfont.  So I went back into Bass, loaded the midi plugin, initialized a soundfont, and set the font. Below should be most of the relevant code (In mine I have a bunch that checks return values...everything is coming back with a valid handle, and the soundfont part returns 'true' for loading the font...

                Bass.BASS_PluginLoad("bassmidi.dll");
                Bass.BASS_Init(-1, 441000, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)
                int stream = BassMidi.BASS_MIDI_StreamCreateFile(@"Track3.mid", 0, 0, BASSFlag.BASS_DEFAULT, 0);
               // Setup sound fonts
                int soundFont = BassMidi.BASS_MIDI_FontInit("Setzer's_SPC_Soundfont.sf2");
                BASS_MIDI_FONT[] newfonts = new BASS_MIDI_FONT[1];
                newfonts[0] = new BASS_MIDI_FONT(soundFont, -1, -1);
                if (soundFont == 0)
                {
                    DebugOutput.Text += "Error loading soundfont!";
                }
                bool FontValue = BassMidi.BASS_MIDI_StreamSetFonts(stream, newfonts, 1);
                Bass.BASS_ChannelPlay(stream, false);

ChannelPlay returns true. SoundFont gets a handle of 1.  Yet I hear no audio. If I play it in xmplay...same midi, same soundfont, things work.  The soundfont and midi are renames of ones taken from this site.  Any ideas on what I'm missing?

radio42

regarding 1) No, the Bass.Misc namespace is not included, as especially the visual stuff contained in it is not supported under WindowsStore. This is a Microsoft limitation they again added to their .Net implementation for Windows universal - so I guess you need blame MS for that ;-)

regarding 2) Looks okay for me, may be Ian knows more...?

Ian @ un4seen

Quote from: Jfarronewfonts[0] = new BASS_MIDI_FONT(soundFont, -1, -1);

When using all presets from a soundfont (preset=-1), the BASS_MIDI_FONT "bank" member is a base number that's added to the soundfont's bank numbers. So bank=-1 means that the soundfont's bank numbers are lowered by 1, eg. when a MIDI file requests bank 0, it will use bank 1 from the soundfont. You will probably want to do this instead:

                newfonts[0] = new BASS_MIDI_FONT(soundFont, -1, 0);

Jfarro

Thankyou!!  That fixed it.  Appreciate the quick and accurate reply.  And now I'm stoked to have it working :)

It's a shame the store apps don't support the stuff required for the Visuals namespace. I'll see what I can roll on my own using what's there.

Jfarro

Ok, got a new question.

I'm using the store StorageFolder/StorageFiles to navigate to the Music directory.  I also specify access to the Music folder in my Manifest.  Essentially I should have full access to the music folder.

I bind to the storagefiles into a listbox, and on click I call Initialize and then StreamCreateFile

This looks like:
StorageFile selected = (StorageFile)SongList.SelectedItem;
            string songPath = selected.Path;

            Button action = (Button)sender;

            switch (action.Name)
            {
                case "PlayButton":
                    {                    
                        player.PlaySong(selected.Path); //player is a class I wrapped Bass.net in.
                        break;
                    }
                
            }

The path ends up in the format: "C:\\Users\\Joseph\\Music\\Jessie J\\Sweet Talker (Deluxe Version)\\01 Ain't Been Done.mp3"

This calls into:

        public bool PlaySong(string PathToSong)
        {
            int stream = Bass.BASS_StreamCreateFile(PathToSong, 0, 0, BASSFlag.BASS_DEFAULT);
            return Bass.BASS_ChannelPlay(stream, false);
        }

I get the error:
Bass.BASS_ErrorGetCode()
BASS_ERROR_FILEOPEN

I can play the file outside of Bass.net.  If I am in the debugger and try to call StreamCreateFile against other paths, I get the same error. However, if I call it against a song that is relative to bass.dll (essentially into my appx directory) then everything works great.

This is on Win10 X64 in a UWP project VS 2015 Update 1.

Update: I tried simplifying the file name to just 'track1.mp3', as well as loading other songs, with no luck. The songs work in media player outside of bass.net, but I understand that removes a boatload of variables when talking Store App development.

Any ideas?

Ian @ un4seen

I believe the issue there is that BASS is currently using the Win32 file functions, which are restricted to the app's own directories in Windows Store apps. To access other directories (eg. the user's Music directory), the Windows Store APIs need to be used, eg. the StorageFile class. Here's a slightly experimental BASS update that does use that stuff for file access:

   www.un4seen.com/stuff/bass-winstore-test.zip

Note that the Windows Store APIs need to be used asynchronously, ie. not in the main/UI thread. So you will now need to call BASS_StreamCreateFile asynchronously. For example, something like this:

Task.Run(() =>
{
stream = Bass.BASS_StreamCreateFile(PathToSong, 0, 0, BASSFlag.BASS_DEFAULT);
Bass.BASS_ChannelPlay(stream, false);
});

This update hasn't been tested much yet, so please report how you get on with it.

Jfarro

Thanks! Yeah that's exactly what I was seeing. My temp workaround was to copy the files using storagefile and then load them so I could continue dev (and also to make sure I wasn't doing something dumb).  I'm super stoked you were able to track that down. And I'm happy to be the tester on this, it's super valuable :)

I'll give this a try tonight and report back, thanks a ton!

Jfarro

Some more updates:
1) The fix to the file load appears to work, I'm now able to use storage apis to load from various places that the user gets access (I'm using the fileopendialog to browse and try various places). This is great :)

2) When I thought about the previous bug, I realized it'd be worth scanning the api set using the Application Certificatin kit to ensure all apis in BASS are 'store compliant'.  I hit the following errors which are being called in the WindowsStore.dll, which would prevent an app from being put in the store currently:

◦API BASS_ChannelGetLevelEx in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelFlags in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetData in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetEnvelopePos in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetLevel in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetMatrix in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetMixer in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetPosition in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelGetPositionEx in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.
◦API BASS_Mixer_ChannelRemove in bassmix.dll is not supported for this application type. Bass.Net.WinStore.dll calls this API.


Let me know if you need help reproing this. The app certication kit for me was located at: :\Program Files (x86)\Windows Kits\10\App Certification Kit

Ian @ un4seen

Good to hear that the new file reading stuff is working well for you.

Regarding the Certification Kit issue, are you currently including BASSMIX.DLL in your app? If not, I guess the Certification Kit may be detecting that those functions are called somewhere in BASS.Net, but it can't see that those code paths aren't actually used in your app. I don't seem to be able to reproduce the problem here though, if I create my own little test app that uses BASS.Net without BASSmix, so I'm not really sure. Does adding BASSMIX.DLL to your project remove the problem?

I did see that the x86 DLLs are currently failing that API test though, due to the compression system. I will see if that can be tweaked, but in the meantime non-compressed x86 DLLs are now up in the package in the 1st post.