ass_setvolume problem

Started by void, 17 Jun '03 - 19:42

void

I am using delphi to create a mp3 player and I did a test to see how the bass get/set volume functions performed and it seems that everytime I start my test program the volume goes up by one from where it was when I last closed the program.

Here is the code I am using

//Start bass and get the initial volume level
procedure TForm1.FormCreate(Sender: TObject);
begin
bass_init(-1,44100,Bass_Device_LeaveVol,Form1.Handle);
TrackBar1.Position := Bass_GetVolume();
end;

//change volume up/down and show its level on a label
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
Bass_SetVolume(TrackBar1.Position);
Label1.Caption := IntToStr(TrackBar1.position);
end;

//Everyone knows what this does
procedure TForm1.FormDestroy(Sender: TObject);
begin
Bass_Free;
end;

I am sure it's a simple mistake on my part but I can't seem to find it.

MB_SOFT

Add BASS_DEVICE_LEAVEVOL flag to your Bass Init call  8)

void

@ MB_SOFT

IF you look at my code you will notice that flag is already there.

Ian @ un4seen

Although DirectSound has 10001 volume levels, in practice, the drivers most likely do not, and so the level will get rounded to some value slightly different to what you/BASS requested.

When you 'get' the volume from BASS, it returns the value that you had previously 'set', even if it's not really that according to the drivers. The only time it asks the drivers is during initialization (BASS_Init). The reason for that is, for example, incase people do something like this...
void ReduceVolume()
{
      volume=BASS_GetVolume();
      if (volume) BASS_SetVolume(volume-1);
}
...it'll behave as expected.

But it's a better idea to use BASS_ChannelSetAttributes (or BASS_SetGlobalVolumes) to adjust the levels, so that the sounds from other apps are not affected by your level changes.

void

So there was nothing wrong with the code that I was using ?

What I mean is if you ran that code on your machine you would get the same results as I did. I just want to know if this is a problem on my machine only or is it something that happens on everyones machine.

I to would rather use the Bass_SetGlobalVolumes and Bass_ChannelSetAttributes functions but the problem I am having is when I try to retrieve those values via the Bass_GetGlobalVolumes and Bass_GetChannelAttributes functions.

If anyone could show me an example (in delphi) of how to use the Bass_GetGlobalVolumes and Bass_ChannelGetAttributes functions then that would help out alot because the bass documentation does not really explain it at all.

Thx,

engineeer

QuoteIf anyone could show me an example (in delphi) of how to use the Bass_GetGlobalVolumes and Bass_ChannelGetAttributes functions then that would help out alot because the bass documentation does not really explain it at all.
I think that bass documentation DOES explain alot. Bass_GetGlobalVolumes and Bass_ChannelGetAttributes are simple functions, and there's nothing extra to explain. All you have to do is to learn some basics of programming.  ;)

void

@ engineeer

in the docs it say to set it up like this
QuoteParameters
handle The channel handle... a HCHANNEL, HMUSIC, HSTREAM, or CDCHANNEL.
freq The sample rate... NULL = don't retrieve it.
volume The volume... NULL = don't retrieve it.
pan The panning position... NULL = don't retrieve it.

so in delphi I do this.

procedure TForm1.FormCreate(Sender: TObject);
var
freq,vol : DWORD;
pan : Integer;
begin
BASS_ChannelGetAttributes(handle,NULL,vol,NULL);
end;

And guess what ? ..... Delphi give me an error saying
QuoteTypes of actual and formal var parameters must be identical

so I am doing as the docs say to do and I am getting the error ... so if it was simple then it would work as documented. And you are right I am not a guru, infact this is like the 2nd week I have ever used delphi in my life and my only programming experience is with php so my knowledge is limited and thus was the reason I asked for an example from a more exp programmer.

Guess I should just stick with what I know and forget about programming in delphi all together.

DanaPaul

#7
QuoteBASS_ChannelGetAttributes(handle,NULL,vol,NULL);

In this example "handle" is undefined because you are calling the BASS_ChannelGetAttributes function within your TForm.Create method, and "handle" will correspond to your TForm.handle once it is created.  Do not use "handle" to represent a Bass Channel, Stream, etc.

Try this...
function TForm1.GetVolulme : Integer;
var freq, volume : DWORD; Pan : Integer;
begin
  BASS_ChannelGetAttributes(fChannel, freq, volume, Pan);
    result := volume;
  end;

Quoteso I am doing as the docs say to do and I am getting the error ... so if it was simple then it would work as documented.

Yes, you are doing as the (Bass) Doc's specify, however, Delphi with its strict type checking is preventing you from doing something that the compiler (Delphi) doesn't expect.  The Delphi flavor of the Bass header files have declared the BASS_ChannelGetAttributes function as follows...

BASS_ChannelGetAttributes = function (handle: DWORD; var freq, volume: DWORD; var pan: Integer): BOOL; stdcall;

In this declaration "var" is actually a memory location where Bass (the DLL) can write a (return) value.  Delphi will not allow you to use a "var" named "null".  If the function was declared as follows...

BASS_ChannelGetAttributes = function (handle: DWORD; freq, volume: pDWORD; pan: pInteger): BOOL; stdcall;

...then you would be able to declare unused parameters as "nil."  However, this second declaration will not work as expected because Bass is expecting a memory location, not a pointer to a memory location.  And, for what its worth, pointers to variables are a bitch to work with for folks with little experience using pointers.

QuoteGuess I should just stick with what I know and forget about programming in delphi all together.

I don't know crap abount PHP but I can assure you that hunkering down and learning Delphi will not dissapoint you in the long run.

One of the suggestions that Ian posted was to use Global volumes...
function TForm1.GetGainVolume : Integer;
var MVol, SVol, STVol : DWORD;
begin
  BASS_GetGlobalVolumes(MVol, SVol, STVol);
  result := MVol;
  end;

To summarize, live with Bass retrieving/returning all values when calling BASS_ChannelGetAttributes or use the other functions that are more specific, such as BASS_SetGlobalVolumes.

void

@DanaPaul

Thank you very much again for you help it helped me in more ways then you know because my next question was going to be once I was able to get the channel attibutes how would I go about displaying just a single attribute and from what I am reading that is not possible so I could not just display the channels volume without also displaying the freq and pan attributes at the same time. (not the way I would have wanted it but I guess I will live with it)

As for learning delphi goes I DO want to learn it and have been trying very hard to learn it as I go but I think this approach is not working very well because I have to stop at every other line of code and pull a few more hairs out because it's not working the way I thought it would. I think coming from a rather easily structured language like php to a more complex structure of language like pascal is doing more harm then good because I try to do things the "php way" instead of the "pascal way" so in alot of ways I wish I did not know anything about php either.

The logic behind delpi is alot like it is in php (as well as other languages I am sure) it's just the structure that I don't seem to understand as I said before so if there are any resources (books, sites, etc) that you or anyone else knows of that will help in that area then plz post and thx again.

DanaPaul

#9
Quoteif there are any resources (books, sites, etc) that you or anyone else knows of that will help in that area then plz post and thx again.

There are hundreds of Delphi sites with useful Objects, enhancements, and code.  However, the most useful resource is the original code that comes with Delphi.  The Windows.pas, SysUtils.pas, Classes.pas, MPlayer.pas... units themselves.

I would suggest working with the examples that came with Bass, and visiting a few sites to download related multimedia objects that include its own source code.  A must visit site and must have VCL component suite are...

www.torrey.net

and...

http://www.torry.net/vcl/packs/huge/rxlib.zip

RxLib includes some very useful Components and utilities with full source code.

A book that I read cover to cover when I first got Delphi years ago is "Delphi Unleashed."  It comes with a CD, examples, tutorials, and source code on a wide variety of subjects :)

DanaPaul


Quotehow would I go about displaying just a single attribute

Try this...


procedure TForm1.DisplayVolume(Sender: TObject);
var freq, volume : DWORD; Pan : Integer;
begin
 BASS_ChannelGetAttributes(fChannel, freq, volume, Pan);
 Label1.Caption := IntToStr(volume);
 end;

Does this answer your question as I read it?

void

Thx DanaPaul,

I was able to get this one on my own after messing around with things abit (oddly enough I know) it returns some number like 938230 though but I will try to figure out what that is and convert it to a real number that humans can understand.

Thanks Again for all your help

void

nvm I figured that out too ...it seems you get that odd number if a stream is not currently being played or atleast that is how it is on my system. when i started the stream it shows up as 100 which I am guessing is what it's supposed to show by default.

Sheep

Does anyone notice that if I play a file with any other sound application while running a bass app, the volume is quite low, and if I close the bass app, while playing in a differnt app, the volume rise again.

Anyone has idea's how to solve this?