BASS Module (Mac)

BlitzMax Forums/BlitzMax Programming/BASS Module (Mac)

I've decided to change from FMOD to BASS (as FMOD isn't Universal), and I'm also getting BlitzMax to accept my DYLIB and the BASS one too.

I'm using a modified BMK of course, and its almost working. I just get the following now :

/usr/bin/ld: warning can't open dynamic library: @executable_path/libbass.dylib referenced from: /Users/nicholaskingsley/Documents/BlitzMax/FMOD/libfmod.dylib (checking for undefined symbols may be affected) (No such file or directory, errno = 2)
/usr/bin/ld: Undefined symbols:
_BASS_GetVersion referenced from libFMod expected to be defined in @executable_path/libbass.dylib
collect2: ld returned 1 exit status
Build Error: Failed to link /Users/nicholaskingsley/Documents/BlitzMax/FMOD/TestFMod.debug.app/Contents/MacOS/TestFMod.debug
Process complete



The problem is @executable_path isn't either the place where the BlitzMax source is or the BlitzMax/tmp - is it possible to append my own to this (or find out where the executable paths are) ?

Finally got it sorted - had to put the library file elsewhere in my home directory.

BASS is running quite well on the Mac now.

cool! can you give a hint for starters on how to get BASS running on a Mac under BlitzMax?

Indeed I shall.

First off, there is a strange problem with it : Sometimes BASS just wont play streamed music when the program is run from the IDE, although through Finder its okay. Whether this also happens with Windows, I dont know.

The reason for using BASS, rather than FMOD is that the BASS DYLIB is Universal, rather than FMOD'S being Intel or PPC (which resulted in problems with my interface code). Plus, I'm more used to BASS too.

I found I had to put the LIBBASS.DYLIB into the lib directory of the home directory for the current user.

This is the interface code. There's nothing particularly hard or unusual in it, and it doesn't have everything from BASS in it.

/*
 *  BASS.c
 *  BASS
 *
 *  Created by Nicholas Kingsley on 20/07/2007.
 *  Copyright 2007 __MyCompanyName__. All rights reserved.
 *
 */
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "BASS.h"

#include "/Developer/bass23-osx/bass.h"

BASS_CHANNELINFO	channelInfo;
int specpos;

//----------System
extern DWORD BASSGetVersion(void)
{
	return BASS_GetVersion();
}

extern char BASSInitialise(int device,int freq,int flags)
{
	memset(&channelInfo,(char) 0,sizeof(channelInfo));
	specpos=0;
	return BASS_Init(device,freq,flags,0,NULL);
}

extern char BASSStart()
{
	return BASS_Start();
}

extern int BASSErrorGetCode(void)
{
	return BASS_ErrorGetCode();
}

extern char BASSFree(void)
{
	return BASS_Free();
}

extern char *BASSGetDeviceDescription(DWORD device)
{
	return (char *) BASS_GetDeviceDescription(device);
}

//------------Samples
extern DWORD BASSSampleLoad(char *fileName,DWORD offset,DWORD length,DWORD max,DWORD flags)
{
	return (DWORD) BASS_SampleLoad(0,fileName,offset,length,max,flags);
}
 
//------------Streams
extern DWORD BASSStreamCreateFile(char *fileName,DWORD offset,DWORD length,DWORD flags)
{
	return ((DWORD) BASS_StreamCreateFile(0,fileName,offset,length,flags));
}

extern char BASSStreamFree(DWORD handle)
{
	return BASS_StreamFree((HSTREAM) handle);
}

//------------Channels
extern char BASSChannelPlay(DWORD handle,char restart)
{
	return BASS_ChannelPlay(handle,restart);
}

extern QWORD BASSChannelGetPosition(DWORD handle)
{
	return BASS_ChannelGetPosition(handle);
}

extern QWORD BASSChannelGetLength(DWORD handle)
{
	return BASS_ChannelGetLength(handle);
}

extern char BASSGetChannelInfo(DWORD handle)
{
	return BASS_ChannelGetInfo(handle,&channelInfo);
}

extern char BASSChannelGetData(DWORD handle,char *buffer,DWORD length)
{
	return BASS_ChannelGetData(handle,buffer,length);
}

//-----------Get information from structures
extern DWORD BASS_ReturnNumberOfChannels(void)
{
	return channelInfo.chans;
}

extern DWORD BASS_ReturnPlaybackFreq(void)
{
	return channelInfo.freq;
}

extern DWORD BASS_ReturnFlags(void)
{
	return channelInfo.flags;
}

extern DWORD BASS_ReturnCType(void)
{
	return channelInfo.ctype;
}

extern DWORD BASS_ReturnOriginalResolution(void)
{
	return channelInfo.origres;
}

extern void BASS_Spectrograph4(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data
		
	for (x=0;x<SPECHEIGHT;x++) 
	{
		y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
		if (y>127) 
		{
			y=127; // cap it
		}
		
		specBuff[x*SPECWIDTH+specpos]=128+y; // plot it
	}
	
	// move marker onto next position
	specpos=(specpos+1)%SPECWIDTH;
	for (x=0;x<SPECHEIGHT;x++) 
	{
		specBuff[x*SPECWIDTH+specpos]=255;
	}
}

extern void BASS_Spectrograph3(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff,DWORD BANDS)
{
register int b0,x,sc,b1,y;
float fft[1024];
float sum;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data
	
	b0=0;
	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<BANDS;x++) 
	{
		sum=0.0;
		
		b1=pow(2,x*10.0/(BANDS-1));
		if (b1>1023) 
		{
			b1=1023;
		}
		
		if (b1<=b0) 
		{
			b1=b0+1; // make sure it uses at least 1 FFT bin
		}
		
		sc=10+b1-b0;
		for (;b0<b1;b0++) 
		{
			sum+=fft[1+b0];
		}
		
		y=(sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4; // scale it
		if (y>SPECHEIGHT) 
		{
			y=SPECHEIGHT; // cap it
		}
		
		while (--y>=0)
		{
			memset(specBuff+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,SPECWIDTH/BANDS-2); // draw bar
		}
	}
}


extern void BASS_Spectrograph2(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y,y1;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data

	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<SPECWIDTH/2;x++) 
	{
		y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
//#else
//				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
//#endif
		if (y>SPECHEIGHT) 
		{
			y=SPECHEIGHT; // cap it
		}
		
		if (x && (y1=(y+y1)/2))
		{
			// interpolate from previous to make the display smoother
			while (--y1>=0) 
			{
				specBuff[y1*SPECWIDTH+x*2-1]=y1+1;
			}
		}
		
		y1=y;
		while (--y>=0)
		{
			specBuff[y*SPECWIDTH+x*2]=y+1; // draw level
		}
	}
}

extern void BASS_Spectrograph1(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
register int c,x,v,y;
float *buf;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetInfo(handle,&channelInfo); 
	buf=alloca(channelInfo.chans*SPECWIDTH*sizeof(float)); // allocate buffer for data
	if (buf==NULL)
	{
		return;
	}
	
	BASS_ChannelGetData(handle,buf,(channelInfo.chans*SPECWIDTH*sizeof(float))|BASS_DATA_FLOAT);
	memset(specBuff,(char) 0,SPECWIDTH*SPECHEIGHT);
	y=0;
	for (c=0; c<channelInfo.chans; c++) 
	{
		for (x=0;x<SPECWIDTH;x++) 
		{
			v=(1-buf[x*channelInfo.chans+c])*SPECHEIGHT/2; // invert and scale to fit display
			if (v<0) 
			{
				v=0;
			}
			else 
			if (v>=SPECHEIGHT) 
			{
				v=SPECHEIGHT-1;
			}
			
			if (!x) 
			{
				y=v;
			}
			
			do { // draw line from previous sample...
				if (y<v) 
				{
					y++;
				}
				else 
				if (y>v) 
				{
					y--;
				}
					
				specBuff[y*SPECWIDTH+x]=c&1?127:1; // left=green, right=red (could add more colours to palette for more chans)
			} while (y!=v);
		}
	}
}


As you can see, I've added the spectrograph routines from the BASS demo.

Okay - onto the BlitzMax stuff. As I mentioned elsewhere, you'll need the modified BMK routine, otherwise this wont work.

Import "-L/Users/nicholaskingsley/Documents/BlitzMax/FMOD"
Import "-lbass"
Import "-lz"
Import "/Users/nicholaskingsley/BASS/BASS.c"

'Import "LibBass.a"

Strict
Local stream:Int
Local length:Long
Const SPECWIDTH:Int=368
Const SPECHEIGHT:Int=127
Local bank:TBank
Local specBuf:TBank
Local bSize:Int
Local aFloat:Float
Local v:Int
Local c:Int
Local x:Int
Local y:Int
Local one:Byte

' Bass error messages
Const BASS_OK:Int=				0	' all is OK
Const BASS_ERROR_MEM:Int=		1	' memory error
Const BASS_ERROR_FILEOPEN:Int=	2	' can't open the file
Const BASS_ERROR_DRIVER:Int=	3	' can't find a free/valid driver
Const BASS_ERROR_BUFLOST:Int=	4	' the sample buffer was lost
Const BASS_ERROR_HANDLE:Int=	5	' invalid handle
Const BASS_ERROR_FORMAT:Int=	6	' unsupported sample format
Const BASS_ERROR_POSITION:Int=	7	' invalid playback position
Const BASS_ERROR_INIT:Int=		8	' BASS_Init has Not been successfully called
Const BASS_ERROR_START:Int=		9	' BASS_Start has Not been successfully called
Const BASS_ERROR_ALREADY:Int=	14	' already initialized/paused/whatever
Const BASS_ERROR_NOPAUSE:Int=	16	' Not paused
Const BASS_ERROR_NOCHAN:Int=	18	' can't get a free channel
Const BASS_ERROR_ILLTYPE:Int=	19	' an illegal Type was specified
Const BASS_ERROR_ILLPARAM:Int=	20	' an illegal parameter was specified
Const BASS_ERROR_NO3D:Int=		21	' no 3D support
Const BASS_ERROR_NOEAX:Int=		22	' no EAX support
Const BASS_ERROR_DEVICE:Int=	23	' illegal device number
Const BASS_ERROR_NOPLAY:Int=	24	' Not playing
Const BASS_ERROR_FREQ:Int=		25	' illegal sample rate
Const BASS_ERROR_NOTFILE:Int=	27	' the stream is Not a file stream
Const BASS_ERROR_NOHW:Int=		29	' no hardware voices available
Const BASS_ERROR_EMPTY:Int=		31	' the Mod music has no sequence data
Const BASS_ERROR_NONET:Int=		32	' no internet connection could be opened
Const BASS_ERROR_CREATE:Int=	33	' couldn't create the file
Const BASS_ERROR_NOFX:Int=		34	' effects are Not available
Const BASS_ERROR_PLAYING:Int=	35	' the channel is playing
Const BASS_ERROR_NOTAVAIL:Int=	37	' requested data is Not available
Const BASS_ERROR_DECODE:Int=	38	' the channel is a "decoding channel"
Const BASS_ERROR_DX:Int=		39	' a sufficient DirectX version is Not installed
Const BASS_ERROR_TIMEOUT:Int=	40	' connection timedout
Const BASS_ERROR_FILEFORM:Int=	41	' unsupported file format
Const BASS_ERROR_SPEAKER:Int=	42	' unavailable speaker
Const BASS_ERROR_VERSION:Int=	43	' invalid BASS version (used by add-ons)
Const BASS_ERROR_CODEC:Int=		44  ' codec is Not available/supported
Const BASS_ERROR_UNKNOWN:Int=	-1	' some other mystery error

' Initialisation variables
Const BASS_DEVICE_8BITS:Int=	1	' use 8 bit resolution, Else 16 bit
Const BASS_DEVICE_MONO:Int=		2	' use mono, Else stereo
Const BASS_DEVICE_3D:Int=		4	' enable 3D functionality
' If the BASS_DEVICE_3D flag is Not specified when initilizing BASS,
' Then the 3D flags (BASS_SAMPLE_3D And BASS_MUSIC_3D) are ignored when
' loading/creating a sample/stream/music.
Const BASS_DEVICE_LATENCY:Int=	256	' calculate device latency (BASS_INFO struct)
Const BASS_DEVICE_SPEAKERS:Int=	2048	' force enabling of speaker assignment
Const BASS_DEVICE_NOSPEAKER:Int=4096	' ignore speaker arrangement

Const BASS_SAMPLE_8BITS:Int=		1	' 8 bit
Const BASS_SAMPLE_FLOAT:Int=		256	' 32-bit floating-point
Const BASS_SAMPLE_MONO:Int=			2	' mono
Const BASS_SAMPLE_LOOP:Int=			4	' looped
Const BASS_SAMPLE_3D:Int=			8	' 3D functionality enabled
Const BASS_SAMPLE_SOFTWARE:Int=		16	' it's NOT using hardware mixing
Const BASS_SAMPLE_MUTEMAX:Int=		32	' muted at Max distance (3D only)
Const BASS_SAMPLE_VAM:Int=			64	' uses the DX7 voice allocation & management
Const BASS_SAMPLE_FX:Int=			128	' old implementation of DX8 effects are enabled
Const BASS_SAMPLE_OVER_VOL:Int=		$10000	' override lowest volume
Const BASS_SAMPLE_OVER_POS:Int=		$20000	' override longest playing
Const BASS_SAMPLE_OVER_DIST:Int=	$30000 ' override furthest from listener (3D only)

Const BASS_STREAM_PRESCAN:Int=		$20000 ' enable pin-point seeking (MP3/MP2/MP1)
Const BASS_MP3_SETPOS:Int=			BASS_STREAM_PRESCAN
Const BASS_STREAM_AUTOFREE:Int=		$40000	' automatically free the stream when it stop/ends
Const BASS_STREAM_RESTRATE:Int=		$80000	' restrict the download rate of internet file streams
Const BASS_STREAM_BLOCK:Int=		$100000' download/play internet file stream in small blocks
Const BASS_STREAM_DECODE:Int=		$200000' don't play the stream, only decode (BASS_ChannelGetData)
Const BASS_STREAM_STATUS:Int=		$800000' give server status info (HTTP/ICY tags) in DOWNLOADPROC

Const BASS_MUSIC_FLOAT:Int=			BASS_SAMPLE_FLOAT ' 32-bit floating-point
Const BASS_MUSIC_MONO:Int=			BASS_SAMPLE_MONO ' force mono mixing (less CPU usage)
Const BASS_MUSIC_LOOP:Int=			BASS_SAMPLE_LOOP ' loop music
Const BASS_MUSIC_3D:Int=			BASS_SAMPLE_3D ' enable 3D functionality
Const BASS_MUSIC_FX:Int=			BASS_SAMPLE_FX ' enable old implementation of DX8 effects
Const BASS_MUSIC_AUTOFREE:Int=		BASS_STREAM_AUTOFREE ' automatically free the music when it stop/ends
Const BASS_MUSIC_DECODE:Int=		BASS_STREAM_DECODE ' don't play the music, only decode (BASS_ChannelGetData)
Const BASS_MUSIC_PRESCAN:Int=		BASS_STREAM_PRESCAN	' calculate playback length
Const BASS_MUSIC_CALCLEN:Int=		BASS_MUSIC_PRESCAN
Const BASS_MUSIC_RAMP:Int=			$200	' normal ramping
Const BASS_MUSIC_RAMPS:Int=			$400	' sensitive ramping
Const BASS_MUSIC_SURROUND:Int=		$800	' surround sound
Const BASS_MUSIC_SURROUND2:Int=		$1000	' surround sound (mode 2)
Const BASS_MUSIC_FT2MOD:Int=		$2000	' play .Mod as FastTracker 2 does
Const BASS_MUSIC_PT1MOD:Int=		$4000	' play .Mod as ProTracker 1 does
Const BASS_MUSIC_NONINTER:Int=		$10000	' non-interpolated mixing
Const BASS_MUSIC_POSRESET:Int=		$8000	' stop all notes when moving position
Const BASS_MUSIC_POSRESETEX	:Int=	$400000' stop all notes And reset bmp/etc when moving position
Const BASS_MUSIC_STOPBACK:Int=		$80000	' stop the music on a backwards jump effect
Const BASS_MUSIC_NOSAMPLE:Int=		$100000' don't load the samples

' Speaker assignment flags
Const BASS_SPEAKER_FRONT:Int=		$1000000	' front speakers
Const BASS_SPEAKER_REAR:Int=		$2000000	' rear/side speakers
Const BASS_SPEAKER_CENLFE:Int=		$3000000	' center & LFE speakers (5.1)
Const BASS_SPEAKER_REAR2:Int=		$4000000	' rear center speakers (7.1)
'Const BASS_SPEAKER_N(n)	((n)<<24)	' n'th pair of speakers (max 15)
Const BASS_SPEAKER_LEFT:Int=		$10000000	' modifier: Left
Const BASS_SPEAKER_RIGHT:Int=		$20000000	' modifier: Right
Const BASS_SPEAKER_FRONTLEFT:Int=	BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_FRONTRIGHT:Int=	BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_REARLEFT	:Int=	BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_REARRIGHT:Int=	BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_CENTER:Int=		BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_LFE:Int=			BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_REAR2LEFT:Int=	BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_REAR2RIGHT:Int=	BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT

Const  BASS_UNICODE:Int=			$80000000

Const  BASS_RECORD_PAUSE:Int=		$8000	' start recording paused

Const BASS_DATA_FLOAT:Int=			$40000000

Graphics 640,480

Extern
	Function BASSGetVersion()
	Function BASSInitialise(device:Int,freq:Int,flags:Int)
	Function BASSChannelGetPosition(handle:Int)
	Function BASSChannelPlay(handle:Int,restart:Int)
	Function BASSChannelGetLength(handle:Int)
	Function BASSChannelGetData(handle:Int,buffer:Byte Ptr,length:Int)
	Function BASSErrorGetCode()
	Function BASSFree()
	Function BASSGetDeviceDescription(device:Int)
	Function BASSGetChannelInfo(handle:Int)
	Function BASSSampleLoad(fileName:Byte Ptr,offset:Int,length:Int,_max:Int,flags:Int)
	Function BASSStart()
	Function BASSStreamCreateFile(fileName:Byte Ptr,offset:Int,length:Int,flags:Int)
	Function BASSStreamFree(handle:Int)
	Function BASS_ReturnNumberOfChannels()
	Function BASS_ReturnPlaybackFreq()
	Function BASS_ReturnFlags()
	Function BASS_ReturnCType()
	Function BASS_ReturnOriginalResolution()
	Function BASS_Spectrograph1(handle:Int,width:Int,height:Int,store:Byte Ptr)
	Function BASS_Spectrograph2(handle:Int,width:Int,height:Int,store:Byte Ptr)
	Function BASS_Spectrograph3(handle:Int,width:Int,height:Int,store:Byte Ptr,bars:Int)
	Function BASS_Spectrograph4(handle:Int,width:Int,height:Int,store:Byte Ptr)
EndExtern

DrawText "Version:"+Hex$(BASSGetVersion()),0,0	' 0x0230001 for the latest version
DrawText "Initialise:"+BASSInitialise(-1,44100,0),0,8
stream=BASSStreamCreateFile("/Users/nicholaskingsley/Music/pulse1.mp3",0,0,BASS_SAMPLE_FLOAT)
'stream=BASSSampleLoad("/Users/nicholaskingsley/Music/pulse1.mp3",0,0,1,1)
DrawText "Stream Handle :"+stream,0,16
'BASSChannelPlay
DrawText BASSChannelPlay(stream,1),0,24
'DrawText BASSStart(),0,24
DrawText "Error Code:"+BASSErrorGetCode(),0,32

'length=BASSChannelGetLength(stream)
'DrawText "Stream Length:"+length,0,48
'DrawText "Error Code:"+BASSErrorGetCode(),0,48+16
'BASSGetChannelInfo(stream)

' Allocate memory for the channel info
bSize=BASS_ReturnNumberOfChannels()*SPECWIDTH*SizeOf aFloat
bank=CreateBank(bSize)
specBuf=CreateBank(SPECWIDTH*SPECHEIGHT)
If bank=Null Or specBuf=Null
	End
EndIf
'a$=BASSGetDeviceDescription(0) ' Look at later
'Print "Description:"+a$

While Not KeyHit(KEY_ESCAPE)
	Cls
	SetColor 255,255,255
	DrawText "Current Position:"+BASSChannelGetPosition(stream),100,100
	DrawText "Number of Channels:"+BASS_ReturnNumberOfChannels(),100,120
	DrawText "Flags:"+BASS_ReturnFlags(),100,140
	DrawText "GetData : "+BASSChannelGetData(stream,BankBuf(bank),bSize | BASS_DATA_FLOAT),100,160
	DrawText "Last error:"+BASSErrorGetCode(),250,160
	
	BASS_Spectrograph3(stream,SPECWIDTH,SPECHEIGHT,BankBuf(specBuf),8)			
	
	For x=0 To SPECWIDTH-1
		For y=0 To SPECHEIGHT-1
			one=PeekByte(specBuf,(y*SPECWIDTH)+x)
			If one
				Select one
					Case	1
						SetColor 255,255,255
					Case 255
						SetColor 255,255,255
					Default
						SetColor 255,255,0
				EndSelect
				
				Plot 100+x,100+y
			EndIf
		Next
	Next
			
	If KeyHit(KEY_SPACE) DrawOval 0,0,640,480
	Flip
EndWhile
BASSStreamFree(stream)
BASSFree()
End


You should probably put that code into [codebox ] tags (without spaces) as oppose to [code ] tags to shorten the length of this thread.

thanks!

Its all shortened now.

It'll be interesting to see if Windows has the same problem as the Mac one...

I am trying your example on a mac and I get:

ld: Undefined symbols:
_BASSChannelGetData
_BASSChannelGetPosition
_BASSChannelPlay
_BASSErrorGetCode
_BASSFree
_BASSGetVersion
...etc

Can I conclude from that that the libbass.dylib is not in the right directory, as you mentioned above?

Also, there is no lib directory in the user directory and creating one doesn't help either ... what am I doing wrong?

You could put the file in a directory used by the PATH variable, although I dont, ie - sbin, bin or something like that.

The lib directory in your home directory has worked for the other Macs I've tried it on. Mine is in /Users/nicholaskingsley/lib

It may be worth seeing if putting the file in with the executable helps.

When you refer to the modified bmk, I guess you are referring to Bruceys thread here?
http://www.blitzmax.com/Community/posts.php?topic=66565#743657

I edited line 217 there, and it didn't change anything. Then I printed the 'cmds' line and found out that the reference to the Bass lib never happens.

On further investigation I found out that I could write anything along the lines of
Import -lSomething

and it doesn't even throw an error. I must be doing something terribly wrong and I don't know where, but I keep trying.

Yes, I am refering to one of Brucey's posts about BMK.

Sounds like you need to change the pathing to the C code, in the Import line. Did you also rebuild the module ?

The BMK module? yes, that's why I see my own prints to debug.

It seems (not confirmed yet) that I have to put the import bass.c statement BEFORE the -lbass - suddenly he recognize that I try to import Bass ....

... and yes, it works now.

On one hand I am glad - on the other one I still don't know what the proper magic was.

So I guess I'll reconstruct the build process (propably starting with a fresh installation of BlitzMax), and I'll post the results here.

So far thank you!

Thats okay!

The import thing does act rather strangely at times...

yes, indeed - the main problem is that for some reason sometimes the BASS.c does not get imported.

I *think* it has soemthing to do with the lower or uppercase of the bmx file that imports the .c file.

The pattern seems to be that if the filename is all uppercase it fails to import/compile.

I don't know if that's the only reason but the test is easy: could you rename your .bmx file to all uppercase (like TEST.BMX), start a fresh BM IDE with no files open, open it via menu and verify/falsify that the BASS.c compilation doesn't happen?

There does seem to be problems with capital letters in certain places - no idea why though

Can you confirm this specific issue?

Why it is - well, after all there's Unix under the hood of OSX, which is case sensitive. So I guess when you mostly develop on a Windows box you'll have a hard time finding every single issue concerning this 'little' difference.

I cant unfortunately - its all working on the Mac, and I want to leave it that way :)
I'll see what I can find at the weekend though.

One thing I have found that it does seem to need / as directory/file seperators, instead of \... But is to be expected really...

I did a sort of minimal application that works on both mac and win32 without modification. It is heavily based on MrTAToad's code above with a few modifications - like with BASSGetDeviceDescription which has to be called like that:
BASSGetDeviceDescription$z(device:Int)
to get a string back.


bass.c
/*
 *  BASS.c
 *  BASS
 *
 *  Created by Nicholas Kingsley on 20/07/2007.
 *  Copyright 2007 __MyCompanyName__. All rights reserved.
 *
 */
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "bass.h"

// #include "/Developer/bass23-osx/bass.h"

BASS_CHANNELINFO	channelInfo;
int specpos;

//----------System
extern DWORD BASSGetVersion(void)
{
	return BASS_GetVersion();
}

extern char BASSInitialise(int device,int freq,int flags)
{
	memset(&channelInfo,(char) 0,sizeof(channelInfo));
	specpos=0;
	return BASS_Init(device,freq,flags,0,NULL);
}

extern char BASSStart()
{
	return BASS_Start();
}

extern int BASSErrorGetCode(void)
{
	return BASS_ErrorGetCode();
}

extern char BASSFree(void)
{
	return BASS_Free();
}

extern char *BASSGetDeviceDescription(DWORD device)
{
	return (char *) BASS_GetDeviceDescription(device);
}

//------------Samples
extern DWORD BASSSampleLoad(char *fileName,DWORD offset,DWORD length,DWORD max,DWORD flags)
{
	return (DWORD) BASS_SampleLoad(0,fileName,offset,length,max,flags);
}

//------------Streams
extern DWORD BASSStreamCreateFile(char *fileName,DWORD offset,DWORD length,DWORD flags)
{
	return ((DWORD) BASS_StreamCreateFile(0,fileName,offset,length,flags));
}

extern char BASSStreamFree(DWORD handle)
{
	return BASS_StreamFree((HSTREAM) handle);
}

//------------Channels
extern char BASSChannelPlay(DWORD handle,char restart)
{
	return BASS_ChannelPlay(handle,restart);
}

extern QWORD BASSChannelGetPosition(DWORD handle)
{
	return BASS_ChannelGetPosition(handle);
}

extern char BASSChannelGetInfo(DWORD handle)
{
	return BASS_ChannelGetInfo(handle,&channelInfo);
}

extern QWORD BASSChannelGetLength(DWORD handle)
{
	return BASS_ChannelGetLength(handle);
}

extern char BASSChannelGetData(DWORD handle,char *buffer,DWORD length)
{
	return BASS_ChannelGetData(handle,buffer,length);
}

//-----------Get information from structures
extern DWORD BASS_ReturnNumberOfChannels(void)
{
	return channelInfo.chans;
}

extern DWORD BASS_ReturnPlaybackFreq(void)
{
	return channelInfo.freq;
}

extern DWORD BASS_ReturnFlags(void)
{
	return channelInfo.flags;
}

extern DWORD BASS_ReturnCType(void)
{
	return channelInfo.ctype;
}

extern DWORD BASS_ReturnOriginalResolution(void)
{
	return channelInfo.origres;
}

extern void BASS_Spectrograph4(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y;

	if (specBuff==NULL)	return;

	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data

	for (x=0;x<SPECHEIGHT;x++)
	{
		y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
		if (y>127)
		{
			y=127; // cap it
		}

		specBuff[x*SPECWIDTH+specpos]=128+y; // plot it
	}

	// move marker onto next position
	specpos=(specpos+1)%SPECWIDTH;
	for (x=0;x<SPECHEIGHT;x++)
	{
		specBuff[x*SPECWIDTH+specpos]=255;
	}
}

extern void BASS_Spectrograph3(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff,DWORD BANDS)
{
register int b0,x,sc,b1,y;
float fft[1024];
float sum;

	if (specBuff==NULL)	return;

	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data

	b0=0;
	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<BANDS;x++)
	{
		sum=0.0;

		b1=pow(2,x*10.0/(BANDS-1));
		if (b1>1023)
		{
			b1=1023;
		}

		if (b1<=b0)
		{
			b1=b0+1; // make sure it uses at least 1 FFT bin
		}

		sc=10+b1-b0;
		for (;b0<b1;b0++)
		{
			sum+=fft[1+b0];
		}

		y=(sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4; // scale it
		if (y>SPECHEIGHT)
		{
			y=SPECHEIGHT; // cap it
		}

		while (--y>=0)
		{
			memset(specBuff+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,SPECWIDTH/BANDS-2); // draw bar
		}
	}
}


extern void BASS_Spectrograph2(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y,y1;

	if (specBuff==NULL)	return;

	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data

	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<SPECWIDTH/2;x++)
	{
		y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
//#else
//				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
//#endif
		if (y>SPECHEIGHT)
		{
			y=SPECHEIGHT; // cap it
		}

		if (x && (y1=(y+y1)/2))
		{
			// interpolate from previous to make the display smoother
			while (--y1>=0)
			{
				specBuff[y1*SPECWIDTH+x*2-1]=y1+1;
			}
		}

		y1=y;
		while (--y>=0)
		{
			specBuff[y*SPECWIDTH+x*2]=y+1; // draw level
		}
	}
}

extern void BASS_Spectrograph1(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
register int c,x,v,y;
float *buf;

	if (specBuff==NULL)	return;

	BASS_ChannelGetInfo(handle,&channelInfo);
	buf=alloca(channelInfo.chans*SPECWIDTH*sizeof(float)); // allocate buffer for data
	if (buf==NULL)
	{
		return;
	}

	BASS_ChannelGetData(handle,buf,(channelInfo.chans*SPECWIDTH*sizeof(float))|BASS_DATA_FLOAT);
	memset(specBuff,(char) 0,SPECWIDTH*SPECHEIGHT);
	y=0;
	for (c=0; c<channelInfo.chans; c++)
	{
		for (x=0;x<SPECWIDTH;x++)
		{
			v=(1-buf[x*channelInfo.chans+c])*SPECHEIGHT/2; // invert and scale to fit display
			if (v<0)
			{
				v=0;
			}
			else
			if (v>=SPECHEIGHT)
			{
				v=SPECHEIGHT-1;
			}

			if (!x)
			{
				y=v;
			}

			do { // draw line from previous sample...
				if (y<v)
				{
					y++;
				}
				else
				if (y>v)
				{
					y--;
				}

				specBuff[y*SPECWIDTH+x]=c&1?127:1; // left=green, right=red (could add more colours to palette for more chans)
			} while (y!=v);
		}
	}
}


minimal.bmx
Strict 

Import "-lbass"

Import "bass.c"


Local stream:Int
Local length:Long
Const SPECWIDTH:Int=368
Const SPECHEIGHT:Int=127
Local bank:TBank
Local specBuf:TBank
Local bSize:Int
Local aFloat:Float
Local v:Int
Local c:Int
Local x:Int
Local y:Int
Local one:Byte

' Bass error messages
Const BASS_OK:Int=				0	' all is OK
Const BASS_ERROR_MEM:Int=		1	' memory error
Const BASS_ERROR_FILEOPEN:Int=	2	' can't open the file
Const BASS_ERROR_DRIVER:Int=	3	' can't find a free/valid driver
Const BASS_ERROR_BUFLOST:Int=	4	' the sample buffer was lost
Const BASS_ERROR_HANDLE:Int=	5	' invalid handle
Const BASS_ERROR_FORMAT:Int=	6	' unsupported sample format
Const BASS_ERROR_POSITION:Int=	7	' invalid playback position
Const BASS_ERROR_INIT:Int=		8	' BASS_Init has Not been successfully called
Const BASS_ERROR_START:Int=		9	' BASS_Start has Not been successfully called
Const BASS_ERROR_ALREADY:Int=	14	' already initialized/paused/whatever
Const BASS_ERROR_NOPAUSE:Int=	16	' Not paused
Const BASS_ERROR_NOCHAN:Int=	18	' can't get a free channel
Const BASS_ERROR_ILLTYPE:Int=	19	' an illegal Type was specified
Const BASS_ERROR_ILLPARAM:Int=	20	' an illegal parameter was specified
Const BASS_ERROR_NO3D:Int=		21	' no 3D support
Const BASS_ERROR_NOEAX:Int=		22	' no EAX support
Const BASS_ERROR_DEVICE:Int=	23	' illegal device number
Const BASS_ERROR_NOPLAY:Int=	24	' Not playing
Const BASS_ERROR_FREQ:Int=		25	' illegal sample rate
Const BASS_ERROR_NOTFILE:Int=	27	' the stream is Not a file stream
Const BASS_ERROR_NOHW:Int=		29	' no hardware voices available
Const BASS_ERROR_EMPTY:Int=		31	' the Mod music has no sequence data
Const BASS_ERROR_NONET:Int=		32	' no internet connection could be opened
Const BASS_ERROR_CREATE:Int=	33	' couldn't create the file
Const BASS_ERROR_NOFX:Int=		34	' effects are Not available
Const BASS_ERROR_PLAYING:Int=	35	' the channel is playing
Const BASS_ERROR_NOTAVAIL:Int=	37	' requested data is Not available
Const BASS_ERROR_DECODE:Int=	38	' the channel is a "decoding channel"
Const BASS_ERROR_DX:Int=		39	' a sufficient DirectX version is Not installed
Const BASS_ERROR_TIMEOUT:Int=	40	' connection timedout
Const BASS_ERROR_FILEFORM:Int=	41	' unsupported file format
Const BASS_ERROR_SPEAKER:Int=	42	' unavailable speaker
Const BASS_ERROR_VERSION:Int=	43	' invalid BASS version (used by add-ons)
Const BASS_ERROR_CODEC:Int=		44  ' codec is Not available/supported
Const BASS_ERROR_UNKNOWN:Int=	-1	' some other mystery error

' Initialisation variables
Const BASS_DEVICE_8BITS:Int=	1	' use 8 bit resolution, Else 16 bit
Const BASS_DEVICE_MONO:Int=		2	' use mono, Else stereo
Const BASS_DEVICE_3D:Int=		4	' enable 3D functionality
' If the BASS_DEVICE_3D flag is Not specified when initilizing BASS,
' Then the 3D flags (BASS_SAMPLE_3D And BASS_MUSIC_3D) are ignored when
' loading/creating a sample/stream/music.
Const BASS_DEVICE_LATENCY:Int=	256	' calculate device latency (BASS_INFO struct)
Const BASS_DEVICE_SPEAKERS:Int=	2048	' force enabling of speaker assignment
Const BASS_DEVICE_NOSPEAKER:Int=4096	' ignore speaker arrangement

Const BASS_SAMPLE_8BITS:Int=		1	' 8 bit
Const BASS_SAMPLE_FLOAT:Int=		256	' 32-bit floating-point
Const BASS_SAMPLE_MONO:Int=			2	' mono
Const BASS_SAMPLE_LOOP:Int=			4	' looped
Const BASS_SAMPLE_3D:Int=			8	' 3D functionality enabled
Const BASS_SAMPLE_SOFTWARE:Int=		16	' it's NOT using hardware mixing
Const BASS_SAMPLE_MUTEMAX:Int=		32	' muted at Max distance (3D only)
Const BASS_SAMPLE_VAM:Int=			64	' uses the DX7 voice allocation & management
Const BASS_SAMPLE_FX:Int=			128	' old implementation of DX8 effects are enabled
Const BASS_SAMPLE_OVER_VOL:Int=		$10000	' override lowest volume
Const BASS_SAMPLE_OVER_POS:Int=		$20000	' override longest playing
Const BASS_SAMPLE_OVER_DIST:Int=	$30000 ' override furthest from listener (3D only)

Const BASS_STREAM_PRESCAN:Int=		$20000 ' enable pin-point seeking (MP3/MP2/MP1)
Const BASS_MP3_SETPOS:Int=			BASS_STREAM_PRESCAN
Const BASS_STREAM_AUTOFREE:Int=		$40000	' automatically free the stream when it stop/ends
Const BASS_STREAM_RESTRATE:Int=		$80000	' restrict the download rate of internet file streams
Const BASS_STREAM_BLOCK:Int=		$100000' download/play internet file stream in small blocks
Const BASS_STREAM_DECODE:Int=		$200000' don't play the stream, only decode (BASS_ChannelGetData)
Const BASS_STREAM_STATUS:Int=		$800000' give server status info (HTTP/ICY tags) in DOWNLOADPROC

Const BASS_MUSIC_FLOAT:Int=			BASS_SAMPLE_FLOAT ' 32-bit floating-point
Const BASS_MUSIC_MONO:Int=			BASS_SAMPLE_MONO ' force mono mixing (less CPU usage)
Const BASS_MUSIC_LOOP:Int=			BASS_SAMPLE_LOOP ' loop music
Const BASS_MUSIC_3D:Int=			BASS_SAMPLE_3D ' enable 3D functionality
Const BASS_MUSIC_FX:Int=			BASS_SAMPLE_FX ' enable old implementation of DX8 effects
Const BASS_MUSIC_AUTOFREE:Int=		BASS_STREAM_AUTOFREE ' automatically free the music when it stop/ends
Const BASS_MUSIC_DECODE:Int=		BASS_STREAM_DECODE ' don't play the music, only decode (BASS_ChannelGetData)
Const BASS_MUSIC_PRESCAN:Int=		BASS_STREAM_PRESCAN	' calculate playback length
Const BASS_MUSIC_CALCLEN:Int=		BASS_MUSIC_PRESCAN
Const BASS_MUSIC_RAMP:Int=			$200	' normal ramping
Const BASS_MUSIC_RAMPS:Int=			$400	' sensitive ramping
Const BASS_MUSIC_SURROUND:Int=		$800	' surround sound
Const BASS_MUSIC_SURROUND2:Int=		$1000	' surround sound (mode 2)
Const BASS_MUSIC_FT2MOD:Int=		$2000	' play .Mod as FastTracker 2 does
Const BASS_MUSIC_PT1MOD:Int=		$4000	' play .Mod as ProTracker 1 does
Const BASS_MUSIC_NONINTER:Int=		$10000	' non-interpolated mixing
Const BASS_MUSIC_POSRESET:Int=		$8000	' stop all notes when moving position
Const BASS_MUSIC_POSRESETEX	:Int=	$400000' stop all notes And reset bmp/etc when moving position
Const BASS_MUSIC_STOPBACK:Int=		$80000	' stop the music on a backwards jump effect
Const BASS_MUSIC_NOSAMPLE:Int=		$100000' don't load the samples

' Speaker assignment flags
Const BASS_SPEAKER_FRONT:Int=		$1000000	' front speakers
Const BASS_SPEAKER_REAR:Int=		$2000000	' rear/side speakers
Const BASS_SPEAKER_CENLFE:Int=		$3000000	' center & LFE speakers (5.1)
Const BASS_SPEAKER_REAR2:Int=		$4000000	' rear center speakers (7.1)
'Const BASS_SPEAKER_N(n)	((n)<<24)	' n'th pair of speakers (max 15)
Const BASS_SPEAKER_LEFT:Int=		$10000000	' modifier: Left
Const BASS_SPEAKER_RIGHT:Int=		$20000000	' modifier: Right
Const BASS_SPEAKER_FRONTLEFT:Int=	BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_FRONTRIGHT:Int=	BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_REARLEFT	:Int=	BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_REARRIGHT:Int=	BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_CENTER:Int=		BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_LFE:Int=			BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT
Const BASS_SPEAKER_REAR2LEFT:Int=	BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT
Const BASS_SPEAKER_REAR2RIGHT:Int=	BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT

Const  BASS_UNICODE:Int=			$80000000

Const  BASS_RECORD_PAUSE:Int=		$8000	' start recording paused

Const BASS_DATA_FLOAT:Int=			$40000000

Extern
	Function BASSGetVersion()
	Function BASSInitialise(device:Int,freq:Int,flags:Int)
	Function BASSChannelGetPosition(handle:Int)
	Function BASSChannelPlay(handle:Int,restart:Int)
	Function BASSChannelGetLength(handle:Int)
	Function BASSChannelGetData(handle:Int,buffer:Byte Ptr,length:Int)
	Function BASSErrorGetCode()
	Function BASSFree()
	Function BASSGetDeviceDescription$z(device:Int)
	Function BASSChannelGetInfo(handle:Int)
	Function BASSSampleLoad(fileName:Byte Ptr,offset:Int,length:Int,_max:Int,flags:Int)
	Function BASSStart()
	Function BASSStreamCreateFile(fileName:Byte Ptr,offset:Int,length:Int,flags:Int)
	Function BASSStreamFree(handle:Int)
	Function BASS_ReturnNumberOfChannels()
	Function BASS_ReturnPlaybackFreq()
	Function BASS_ReturnFlags()
	Function BASS_ReturnCType()
	Function BASS_ReturnOriginalResolution()
	Function BASS_Spectrograph1(handle:Int,width:Int,height:Int,store:Byte Ptr)
	Function BASS_Spectrograph2(handle:Int,width:Int,height:Int,store:Byte Ptr)
	Function BASS_Spectrograph3(handle:Int,width:Int,height:Int,store:Byte Ptr,bars:Int)
	Function BASS_Spectrograph4(handle:Int,width:Int,height:Int,store:Byte Ptr)
EndExtern


Function checkForErrors:Int()
	Local bassError:Int = BASSErrorGetCode()
	If bassError <> 0
	  Print "An Error has occured: "+bassError
		End
	Else
		Return 0
	EndIf
EndFunction

Graphics 640,480

Print "Version:"+Hex$(BASSGetVersion())
BASSInitialise(1,44100,0)


stream=BASSStreamCreateFile("test.mp3",0,0,0)
checkForErrors()

BASSChannelPlay(stream, 0)
checkForErrors()

Print "Length: " + BASSChannelGetLength(stream)
checkForErrors()

Print "Device Description:  " + BASSGetDeviceDescription(1)

While Not KeyHit(KEY_ESCAPE)
	Cls
	SetColor 255,255,255
	DrawText "Current Position:"+BASSChannelGetPosition(stream),100,100
	Flip
EndWhile
BASSStreamFree(stream)
BASSFree()
End


Probably easier to read than my test code :)

I cant seem to replicate the case sensitive compiler problems, so it might have been just me...

I had no luck of compiling the above code"without modifications" on Win32. I found that changing -lbass to -Lbass is at least reporting something different than "cannot find -lbass", to "undefined reference to `BASS_Init@20".

I have the modified BMK (been compiling some of Brucey's modules without a glitch). I have bass.h . I am surely missing something obvious ...

... the DLL?

nope! not that!

You do need to copy the BASS.DLL into the same place as the executable. For MacOS machines, you copy the dylib file.

I did. I have the dll in the system32 folder as well. It seems less and less obvious!

I have these console outputs for all the (apparently un-) declared bass functions in bass.c :
C:/BASS/BASS/.bmx/BASS.c.debug.win32.x86.o(.text+0x34):BASS.c: undefined reference to `BASS_Init@20'

Debug or release, no difference. -l

Does a 'build modules' in general work for you?

Yes from BRL mods to Axe or BaH mods, it compiles everything.

It looks like its mangling the function name, and thus it could think your using C++, instead of C, for some reason...

The other possibility is it cant find the BASS header - I presume you've installed the BASS SDK ? If so, is the header in with the rest of the code ? If not, you'll probably need to change the #include "bass.h" to the full path (ie, something like #include "c:\program files\bass\bass.h")

It finds the bass.h, when I type something "wrong" in it, it throws an error. So still the C++ case to investigate ...
Could you send me your bass.h, I suspect something has maybe changed in it compared to the version you are using. My email address is in my profile. Thanks

...maybe it's the mysterious 'the case of the case sensitive filenames' case? In any case, if you have enough mailbox, I'll send you the whole project.

The bass.h file is the one from the BASS SDK - I certainly haven't needed to alter it.

Try using this set of headers in the C file (uncommenting out the //define to activate the WIN32 path - if your using Windows) :

//#define WIN32

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"

#ifdef WIN32
	// Windows
	#define BASSDEF(f) (WINAPI *f) // define the functions as pointers
	#include "c:\program files\BASS\c\bass.h"
	HINSTANCE bass=NULL;
#else
	// OSX Version
	#include "/Developer/bass23-osx/bass.h"
#endif


Well with this header, the bass.c errors disappeared, but Blitzmax throws a Unhandled memory exception error on each call to any bass function.

@Dirk : My mailbox is surely big enough!

That would there is no proper initialisation done - the BASS_Initialisation code should be (for Windows) :

extern char BASSInitialise(int device,int freq,int flags,DWORD windowHandle)
{
	memset(&channelInfo,(char) 0,sizeof(channelInfo));
	specpos=0;
	memset(&diff,(char) 0,sizeof(diff));

#ifdef WIN32
	bass=LoadLibrary("BASS.DLL"); // load BASS
	if (bass)
	{
		BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
		if (BASS_Init)
		{
			BASS_Free=GetProcAddress(bass,"BASS_Free");
			//BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
			BASS_Start=GetProcAddress(bass,"BASS_Start");
			BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode");
			BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad");
			BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel");
			BASS_SampleStop=GetProcAddress(bass,"BASS_SampleStop");
			BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile");
			BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay");
			BASS_ChannelPause=GetProcAddress(bass,"BASS_ChannelPause");
			BASS_ChannelGetPosition=GetProcAddress(bass,"BASS_ChannelGetPosition");
			BASS_ChannelPreBuf=GetProcAddress(bass,"BASS_ChannelPreBuf");
			BASS_StreamFree=GetProcAddress(bass,"BASS_StreamFree");
			BASS_ChannelGetLength=GetProcAddress(bass,"BASS_ChannelGetLength");
			BASS_ChannelGetInfo=GetProcAddress(bass,"BASS_ChannelGetInfo");
			BASS_ChannelGetData=GetProcAddress(bass,"BASS_ChannelGetData");
			BASS_ChannelIsActive=GetProcAddress(bass,"BASS_ChannelIsActive");
			BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop");
			BASS_ChannelSetPosition=GetProcAddress(bass,"BASS_ChannelSetPosition");
			BASS_ChannelSetAttributes=GetProcAddress(bass,"BASS_ChannelSetAttributes");
			BASS_ChannelBytes2Seconds=GetProcAddress(bass,"BASS_ChannelBytes2Seconds");
			BASS_ChannelGetTags=GetProcAddress(bass,"BASS_ChannelGetTags");
			return BASS_Init(device,freq,flags,(HWND) windowHandle,NULL);
		}
		else
		{
			BASS_Free=NULL;
			BASS_ErrorGetCode=NULL;
		}
	}
	
	return -1;
#else
	return BASS_Init(device,freq,flags,0,NULL);
#endif
}


This is so the DLL is loaded when the initilisation routine is called, and without it your trying to call functions that dont exist.

This is the Windows (and updated Mac) version :

/*
 *  BASS.c
 *  BASS
 *
 *  Created by Nicholas Kingsley on 20/07/2007.
 *  Copyright 2007 __MyCompanyName__. All rights reserved.
 *
 */

//#define WIN32

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"

#ifdef WIN32
	// Windows
	#define BASSDEF(f) (WINAPI *f) // define the functions as pointers
	#include "c:\program files\BASS\c\bass.h"
	HINSTANCE bass=NULL;
#else
	// OSX Version
	#include "/Developer/bass23-osx/bass.h"
#endif

BASS_CHANNELINFO	channelInfo;
int specpos;
int diff[4];

//----------System
extern DWORD BASSGetVersion(void)
{
	return BASSVERSION;
}

extern char BASSInitialise(int device,int freq,int flags,DWORD windowHandle)
{
	memset(&channelInfo,(char) 0,sizeof(channelInfo));
	specpos=0;
	memset(&diff,(char) 0,sizeof(diff));

#ifdef WIN32
	bass=LoadLibrary("BASS.DLL"); // load BASS
	if (bass)
	{
		BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init
		if (BASS_Init)
		{
			BASS_Free=GetProcAddress(bass,"BASS_Free");
			//BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
			BASS_Start=GetProcAddress(bass,"BASS_Start");
			BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode");
			BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad");
			BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel");
			BASS_SampleStop=GetProcAddress(bass,"BASS_SampleStop");
			BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile");
			BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay");
			BASS_ChannelPause=GetProcAddress(bass,"BASS_ChannelPause");
			BASS_ChannelGetPosition=GetProcAddress(bass,"BASS_ChannelGetPosition");
			BASS_ChannelPreBuf=GetProcAddress(bass,"BASS_ChannelPreBuf");
			BASS_StreamFree=GetProcAddress(bass,"BASS_StreamFree");
			BASS_ChannelGetLength=GetProcAddress(bass,"BASS_ChannelGetLength");
			BASS_ChannelGetInfo=GetProcAddress(bass,"BASS_ChannelGetInfo");
			BASS_ChannelGetData=GetProcAddress(bass,"BASS_ChannelGetData");
			BASS_ChannelIsActive=GetProcAddress(bass,"BASS_ChannelIsActive");
			BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop");
			BASS_ChannelSetPosition=GetProcAddress(bass,"BASS_ChannelSetPosition");
			BASS_ChannelSetAttributes=GetProcAddress(bass,"BASS_ChannelSetAttributes");
			BASS_ChannelBytes2Seconds=GetProcAddress(bass,"BASS_ChannelBytes2Seconds");
			BASS_ChannelGetTags=GetProcAddress(bass,"BASS_ChannelGetTags");
			return BASS_Init(device,freq,flags,(HWND) windowHandle,NULL);
		}
		else
		{
			BASS_Free=NULL;
			BASS_ErrorGetCode=NULL;
		}
	}
	
	return -1;
#else
	return BASS_Init(device,freq,flags,0,NULL);
#endif
}

extern char BASSStart()
{
	return BASS_Start();
}

extern int BASSErrorGetCode(void)
{
	if (BASS_ErrorGetCode)
	{
		return BASS_ErrorGetCode();
	}
	else
	{
		return -1;
	}
}

extern char BASSFree(void)
{
BOOL result;

	if (BASS_Free)
	{
		result=BASS_Free();
	}
	else
	{
		result=-1;
	}

#ifdef WIN32
	FreeLibrary(bass);
	bass=NULL;
#endif
	return (char) result;
}

extern char *BASSGetDeviceDescription(DWORD device)
{
	return (char *) BASS_GetDeviceDescription(device);
}

//------------Samples
extern DWORD BASSSampleLoad(char *fileName,DWORD offset,DWORD length,DWORD max,DWORD flags)
{
	return (DWORD) BASS_SampleLoad(0,fileName,offset,length,max,flags);
}

//------------Streams
extern DWORD BASSStreamCreateFile(char *fileName,DWORD offset,DWORD length,DWORD flags)
{
	return ((DWORD) BASS_StreamCreateFile(0,fileName,offset,length,flags));
}

extern char BASSStreamFree(DWORD handle)
{
	return BASS_StreamFree((HSTREAM) handle);
}

extern DWORD BASSSampleGetChannel(DWORD handle,char onlyNew)
{
	return (DWORD) BASS_SampleGetChannel((HSAMPLE) handle,(BOOL) onlyNew);
}

extern char BASSSampleStop(DWORD handle)
{
	return BASS_SampleStop(handle);
}

//------------Channels
extern char BASSChannelPlay(DWORD handle,char restart)
{
	return BASS_ChannelPlay(handle,restart);
}

extern char BASSChannelPause(DWORD handle)
{
	return BASS_ChannelPause(handle);
}

extern QWORD BASSChannelGetPosition(DWORD handle)
{
	return BASS_ChannelGetPosition(handle);
}

extern char BASSChannelSetPosition(DWORD handle,QWORD position)
{
	return BASS_ChannelSetPosition(handle,position);
}

extern QWORD BASSChannelGetLength(DWORD handle)
{
	return BASS_ChannelGetLength(handle);
}

extern char BASSGetChannelInfo(DWORD handle)
{
	return BASS_ChannelGetInfo(handle,&channelInfo);
}

extern char BASSChannelGetData(DWORD handle,char *buffer,DWORD length)
{
	return BASS_ChannelGetData(handle,buffer,length);
}

extern DWORD BASSChannelIsActive(DWORD handle)
{
	return BASS_ChannelIsActive(handle);
}

extern char BASSChannelStop(DWORD handle)
{
	return BASS_ChannelStop(handle);
}

extern char BASSChannelSetAttributes(DWORD handle,int freq,int volume,int pan)
{
	return BASS_ChannelSetAttributes(handle,freq,volume,pan);
}

extern DWORD BASSChannelBytes2Seconds(DWORD handle,QWORD pos)
{
float length;

	// Cant return a float for some reason to BlitzMax
	length=BASS_ChannelBytes2Seconds(handle,pos);
	return (DWORD) length;
}

extern char *BASSChannelGetTags(DWORD handle,DWORD tags)
{
	return BASS_ChannelGetTags(handle,tags);
}

extern char BASSChannelPreBuf(DWORD handle,DWORD length)
{
	return BASS_ChannelPreBuf(handle,length);
}

//-----------Get information from structures
extern DWORD BASS_ReturnNumberOfChannels(void)
{
	return channelInfo.chans;
}

extern DWORD BASS_ReturnPlaybackFreq(void)
{
	return channelInfo.freq;
}

extern DWORD BASS_ReturnFlags(void)
{
	return channelInfo.flags;
}

extern DWORD BASS_ReturnCType(void)
{
	return channelInfo.ctype;
}

extern DWORD BASS_ReturnOriginalResolution(void)
{
	return channelInfo.origres;
}

extern void BASS_ClearDiff(void)
{
	memset(&diff,(char) 0,sizeof(diff));
}

extern DWORD BASS_Spectrograph5(DWORD handle,DWORD diffValue,char *storeSpec,DWORD SPECHEIGHT,DWORD BANDS)
{
register int b0,x,sc,b1,y;
float fft[1024];
float sum;
DWORD	result;

	result=0;
	if (BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048))
	{
		b0=0;
		for (x=0;x<BANDS;x++) 
		{
			sum=0.0;
			
			b1=pow(2,x*10.0/(BANDS-1));
			if (b1>1023) 
			{
				b1=1023;
			}
			
			if (b1<=b0) 
			{
				b1=b0+1; // make sure it uses at least 1 FFT bin
			}
			
			sc=10+b1-b0;
			for (;b0<b1;b0++) 
			{
				sum+=fft[1+b0];
			}
			
			y=(int) ((sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4.0); // scale it
			y=(y>SPECHEIGHT ? SPECHEIGHT : \
				y<0 ? 0 : y); 
			
			*(storeSpec+x)=(char) y;
				
			if (labs(diff[x]-y)>diffValue)
			{
				diff[x]=y;
				result=(x==0 ? result | 1 : \
						x==1 ? result | 2 : \
						x==2 ? result | 4 : result | 8);
			}
		}
	}

	return result;
}

extern void BASS_Spectrograph4(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data
		
	for (x=0;x<SPECHEIGHT;x++) 
	{
		y=sqrt(fft[x+1])*3*127; // scale it (sqrt to make low values more visible)
		if (y>127) 
		{
			y=127; // cap it
		}
		
		specBuff[x*SPECWIDTH+specpos]=128+y; // plot it
	}
	
	// move marker onto next position
	specpos=(specpos+1)%SPECWIDTH;
	for (x=0;x<SPECHEIGHT;x++) 
	{
		specBuff[x*SPECWIDTH+specpos]=255;
	}
}

extern void BASS_Spectrograph3(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff,DWORD BANDS)
{
register int b0,x,sc,b1,y;
float fft[1024];
float sum;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data
	
	b0=0;
	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<BANDS;x++) 
	{
		sum=0.0;
		
		b1=pow(2,x*10.0/(BANDS-1));
		if (b1>1023) 
		{
			b1=1023;
		}
		
		if (b1<=b0) 
		{
			b1=b0+1; // make sure it uses at least 1 FFT bin
		}
		
		sc=10+b1-b0;
		for (;b0<b1;b0++) 
		{
			sum+=fft[1+b0];
		}
		
		y=(sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4; // scale it
		if (y>SPECHEIGHT) 
		{
			y=SPECHEIGHT; // cap it
		}
		
		while (--y>=0)
		{
			memset(specBuff+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,SPECWIDTH/BANDS-2); // draw bar
		}
	}
}

extern void BASS_Spectrograph2(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
float fft[1024];
register int x,y,y1;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048); // get the FFT data

	memset(specBuff,0,SPECWIDTH*SPECHEIGHT);
	for (x=0;x<SPECWIDTH/2;x++) 
	{
		y=sqrt(fft[x+1])*3*SPECHEIGHT-4; // scale it (sqrt to make low values more visible)
//#else
//				y=fft[x+1]*10*SPECHEIGHT; // scale it (linearly)
//#endif
		if (y>SPECHEIGHT) 
		{
			y=SPECHEIGHT; // cap it
		}
		
		if (x && (y1=(y+y1)/2))
		{
			// interpolate from previous to make the display smoother
			while (--y1>=0) 
			{
				specBuff[y1*SPECWIDTH+x*2-1]=y1+1;
			}
		}
		
		y1=y;
		while (--y>=0)
		{
			specBuff[y*SPECWIDTH+x*2]=y+1; // draw level
		}
	}
}

extern void BASS_Spectrograph1(DWORD handle,DWORD SPECWIDTH,DWORD SPECHEIGHT,char *specBuff)
{
register int c,x,v,y;
float *buf;

	if (specBuff==NULL)	return;
	
	BASS_ChannelGetInfo(handle,&channelInfo); 
	buf=alloca(channelInfo.chans*SPECWIDTH*sizeof(float)); // allocate buffer for data
	if (buf==NULL)
	{
		return;
	}
	
	BASS_ChannelGetData(handle,buf,(channelInfo.chans*SPECWIDTH*sizeof(float))|BASS_DATA_FLOAT);
	memset(specBuff,(char) 0,SPECWIDTH*SPECHEIGHT);
	y=0;
	for (c=0; c<channelInfo.chans; c++) 
	{
		for (x=0;x<SPECWIDTH;x++) 
		{
			v=(1-buf[x*channelInfo.chans+c])*SPECHEIGHT/2; // invert and scale to fit display
			if (v<0) 
			{
				v=0;
			}
			else 
			if (v>=SPECHEIGHT) 
			{
				v=SPECHEIGHT-1;
			}
			
			if (!x) 
			{
				y=v;
			}
			
			do { // draw line from previous sample...
				if (y<v) 
				{
					y++;
				}
				else 
				if (y>v) 
				{
					y--;
				}
					
				specBuff[y*SPECWIDTH+x]=c&1?127:1; // left=green, right=red (could add more colours to palette for more chans)
			} while (y!=v);
		}
	}
}


Uncommend the //WIN32 part for Windows

Yes! That works with uncommenting //#define WIN32 and using import "-Lbass" instead of "-lbass". Now I am happy :) Thanks a lot.

Knew it some something simple :)