Trouble with struct and qword (bass.dll)

BlitzMax Forums/BlitzMax Programming/Trouble with struct and qword (bass.dll)

Space Fractal(Posted 2007) [#1]
I have got this library mostly to work, but I got some hastle with some things I never can get it to work:

How do I use a unsinged 64 value, wich seen BASS_ChannelSeconds2Bytes function use? It work fully when I only use int, but it dosent work with LONG.

also:
' work
Global BASS_ChannelSeconds2Bytes:Int(handler:Int, time:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelSeconds2Bytes")

' dosent work
Global BASS_ChannelSeconds2Bytes:Long(handler:Int, time:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelSeconds2Bytes")


Another Thing:
I have also a totally mess how to return with struct type things. Even I looked on all threads, Im are lost here.


The def struct is coded as

typedef struct {
 DWORD ctype; // channel type
 const char *name;	// format description
 const char *exts;	// file extension filter (*.ext1;*.ext2;etc...)
} BASS_PLUGINFORM;

typedef struct {
 DWORD version; // version (same form as BASS_GetVersion)
 DWORD formatc; // number of formats
 const BASS_PLUGINFORM *formats; // the array of formats
} BASS_PLUGININFO;


Here is the problem code:

Strict
Import Pub.Win32
TAudio.Load()

Extern
Type TBASS_PLUGINFORM
	Field ctype:Int
	Field Name$
	Field Exts$
	
EndType

Type TBASS_PLUGININFO
	Field version:Int
	Field formatc:Int
	Field formats:TBASS_PLUGINFORM[]
EndType	
EndExtern

Private
	Global RESULT$
	
	Global BASS_MONO=2
	Global BASS_PRESCAN=$20000
	Global BASS_RAMP=$200
	Global BASS_CONFIG_CURVE_VOL=6
	Global BASS_CONFIG_WMA_ASX=$10102
	Global BASS_CONFIG_WMA_BASSFILE=$10103
	
	Global BASS_DLL
	Global BASS_GetConfig:Int(option:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_GetConfig")
	Global BASS_SetConfig:Int(option:Int,value:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_SetConfig")
	Global BASS_ChannelStop:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelStop")
	Global BASS_ChannelPlay:Int(handle:Int,restart:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelPlay")
	Global BASS_Init:Int(device:Int, freq:Int, flags:Int, win:Int, clsid:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_Init")
	Global BASS_ErrorGetCode:Int() "Win32" = GetProcAddress(BASS_DLL,"BASS_ErrorGetCode")
	Global BASS_Free:Int() "Win32" = GetProcAddress(BASS_DLL,"BASS_Free")
	Global BASS_PluginGetInfo:Byte Ptr(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_PluginGetInfo")
	Global BASS_PluginLoad:Int(url:Byte Ptr,flags:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_PluginLoad")
	Global BASS_MusicFree:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_MusicFree")
	Global BASS_MusicLoad:Int(mem:Byte,url:Byte Ptr, offset:Int, length:Int, flags:Int, freq:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_MusicLoad")
	Global BASS_StreamFree:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_StreamFree")
	Global BASS_StreamCreateFile:Int(mem:Byte,url:Byte Ptr, offset:Int, length:Int, flags:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_StreamCreateFile")
	Global BASS_GetDevice$z(device:Byte) "Win32" = GetProcAddress(BASS_DLL,"BASS_GetDeviceDescription")
	Global BASS_ChannelGetLength:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelGetLength")
	Global BASS_ChannelBytes2Seconds:Float(handler:Int, time:Long) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelBytes2Seconds")
	Global BASS_ChannelSeconds2Bytes:Int(handler:Int, time:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelSeconds2Bytes")
	Global BASS_ChannelGetPosition:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelGetPosition")
	Global BASS_ChannelSetPosition:Int(handler:Int, time:Long) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelSetPosition")
	Global BASS_ChannelPause:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelPause")
	Global BASS_ChannelIsActive:Int(handler:Int) "Win32" = GetProcAddress(BASS_DLL,"BASS_ChannelIsActive")

	Global BASSWMA_DLL
	Global BASS_WMA_StreamCreateFile:Int(mem:Byte,url:Byte Ptr, offset:Int, length:Int, flags:Int) "Win32" = GetProcAddress(BASSWMA_DLL,"BASS_WMA_StreamCreateFile")

	Global BASSMIDI_DLL
	Global BASS_MIDI_StreamCreateFile:Int(mem:Byte,url:Byte Ptr, offset:Int, length:Int, flags:Int) "Win32" = GetProcAddress(BASSWMA_DLL,"BASS_MIDI_StreamCreateFile")


Public

TAudio.Setup()
TAudio.Init(1, 44100)

Local Audio:TAudio=New TAudio 

Type TAudio
	Field HANDLER
	Field Format$=""
	Field isPlay=0

	Function getSoundCard$(soundcard)
		RESULT$=bass_getDevice(soundcard)
		Return RESULT$
	EndFunction

	Function Load()
		If Instr(CurrentDir$(),"source",12)
			Path$=CurrentDir$()+"/../win32/data/"
		Else
			Path$=CurrentDir$()+"/data/"
		EndIf
			
		BASS_DLL=LoadLibraryA(Path$+"bass.dll")
		BASSWMA_DLL=LoadLibraryA(Path$+"basswma.dll")
			
	EndFunction
		
	Function Init(device, freq)
		bass_Init(device, freq, 0, 0, 0)
	EndFunction

	Function Setup()
		BASS_SetConfig(BASS_CONFIG_WMA_ASX,1)
		BASS_SetConfig(BASS_CONFIG_WMA_BASSFILE,1)
		BASS_SetConfig(BASS_CONFIG_CURVE_VOL,1)
		
		Local P$=Path$+"bassmidi.dll"
		Local TEST=BASS_PluginLoad(P$,0);
		
		
		Local Info:Byte Ptr=BASS_PluginGetInfo(TEST) '??????? Cant get the object returned in any way
		'Print "VERSION: "+INFO.Version+" COUNT:"+INFO.formatc

		
		MusicExt$=MusicExt$+".mid"

	EndFunction

	Method GetLength:Int()
		' this one DOES work fine, as ling Im dosnet use 64bit qword (INT). 
		' I wich to have the origianl 64bit, not 32 bit.
		Local Length=BASS_ChannelGetLength(Handler);
		Local time:Float=BASS_ChannelBytes2Seconds(Handler,Length);
		Return (Time+1)
	EndMethod
EndType


I removed some code wich dosent have a problem to bring the tread down. Rest of the functions work fine, and got audios played (including plugins), seeked and so on. I do allways have problems with QWORD and other speciel structs.

When I got this to work I would make a example how it can been done, since some others may have same troubles (maybe in code archives).


H&K(Posted 2007) [#2]
How do I use a unsinged 64 value
What I think you do, is write a function in c, (called for example BASS_ChannelSeconds2BytesConvertLong), which converts a long into a unsinged 64 value, and it calls the real BASS_ChannelSeconds2Bytes Function. Then again, if it already works with an Int, why bother.


Chris C(Posted 2007) [#3]
*sigh* why max still doesnt have a full complement of unsigned and signed "native" types is beyond me, that and lack of simple struct support is very much needed!


Space Fractal(Posted 2007) [#4]
I would like do the right, and not convert anything down.

I cant even get the correct pointer to work (BASS return a pointer to the struct).

Even with using peeks(), (or sucks) it would do that way.

Yep I wounder why it dosent have all unsigned elements type (example using a unsinged int).

Im are not good at C, so I have not a clue how to import and call. Maybe I would try to use a function wrapper dll for problem functions in PureBasic instead?


Gabriel(Posted 2007) [#5]
I don't see why it matters. As long as you don't do any arithmetic with the number, it shouldn't make the slightest difference whether the value is signed or unsigned. I interface with values requiring signed and unsigned 32 bit numbers all the time, and it causes no issues at all. I don't see why that should change when it's 64 bits, but perhaps there are other issues here ( 64 bit numbers on 32 bit cpu's perhaps? )

Local Length = BASS_ChannelGetLength(Handler);
Local time:Float = BASS_ChannelBytes2Seconds(Handler,Length);


I mean, you're just getting the length and passing it back. You don't do anything with that value at all, so the bits should remain unchanged, and it should be read as the same value it was when you received it.

Are you sure this is your problem?


Space Fractal(Posted 2007) [#6]
When it using LONG, it return a completly wrong value. I wich to have used long, but is not compativle with qword.


Who was John Galt?(Posted 2007) [#7]
So what's the correct value, and what do you get when you use a long?


Who was John Galt?(Posted 2007) [#8]
...and also....
Do you know that Blitz types are not exactly like a pointer to a struct... theyre like a pointer to a struct with an extra few hidden bytes tacked on (I think?). To get a true pointer to the user defined struct bit have a method that returns a pointer to the first field in your type. Blitz type arrays are like arrays of pointers to struct (again with tacked on bits), whereas BASS seems to be using a C type contiguous array of structs.


LAB[au](Posted 2007) [#9]
@Space Fractal
Hello,

I am busy with testing Bass2.3 mod, found on german forums, however I didn't succeeded in getting a correct value returned by substituting a QWORD with an Int on BASS_ChannelGetLength. Did you? and how?