Question

Based on Bass's documentation, I'm trying to load an ogg file with the code that follows:

var
  FFile : string;
  Music: HSAMPLE; 
  ch: HCHANNEL;
  OpenDialog1 : TOpenDialog;
begin
  Dynamic_Bass.Load_BASSDLL('Library/Bass.dll');
  Dynamic_Bass.BASS_Init(1,44000,Bass_DEVICE_SPEAKERS,0,nil);  
  OpenDialog1 := TOpenDialog.Create(nil);
  if not OpenDialog1.Execute then
    Exit;
  ffile := OpenDialog1.FileName;
  Music := BASS_SampleLoad(FALSE, PChar(ffile), 0, 0, 3, BASS_SAMPLE_OVER_POS);
  ch := BASS_SampleGetChannel(Music, False);
  BASS_ChannelSetAttribute(ch, BASS_ATTRIB_PAN, 0);
  BASS_ChannelSetAttribute(ch, BASS_ATTRIB_VOL, 1);
  BASS_ChannelPlay(ch, False);
  ShowMessage(IntToStr(BASS_ErrorGetCode));
end;

ShowMessage returns 5. Acording to documentation this is Handle error, what means that the error is in the music var. If I comment the lines below BASS_SampleLoad I get error 2. Means the file could not be loaded. So it is an ordinary OGG file. So my question: Am I doing something wrong?

Thanks in advance.

Was it helpful?

Solution

Your code seems to be correct, just make sure you check for errors on each call.

Fixed code:

var
  ffile : string;
  music: HSAMPLE; 
  ch: HCHANNEL;
  opendialog1 : topendialog;

begin 
 if not Dynamic_Bass.Load_BASSDLL('Library/Bass.dll') then
  Exit;
 // change device to -1 which is the default device
 if Dynamic_Bass.BASS_Init(-1,44000,Bass_DEVICE_SPEAKERS,0,nil) then
  begin
   opendialog1 := topendialog.Create(nil);
   try
    if OpenDialog1.Execute then
     begin
      ffile := OpenDialog1.FileName;
      music := BASS_SampleLoad(FALSE, PChar(ffile), 0, 0, 3, BASS_SAMPLE_OVER_POS);
      if music <> 0 then
       begin
        ch := BASS_SampleGetChannel(music, False);
        if ch <> 0 then
         begin
          // omitted, see if the basics work   
          // BASS_ChannelSetAttribute(ch, BASS_ATTRIB_PAN, 0);
          // BASS_ChannelSetAttribute(ch, BASS_ATTRIB_VOL, 1);
          if not BASS_ChannelPlay(ch, False) then
           ShowMessage(inttostr(bass_errorgetcode));
         end
        else
         ShowMessage(inttostr(bass_errorgetcode));
       end
      else
       ShowMessage(inttostr(bass_errorgetcode));
     end;
   finally  
    OpenDialog1.Free;
   end;
  end
 else
  ShowMessage(inttostr(bass_errorgetcode));
end;

UPDATE

I should have seen this sooner, your code fails because BASS_SampleLoad expects the filename in ANSI format, the documentation clearly mentions this, since you have Delphi XE3 and Strings are Unicode, you must supply the BASS_UNICODE flag to indicate this.

so the Bass_SampleLoad line becomes:

music := BASS_SampleLoad(FALSE, PChar(ffile), 0, 0, 3, BASS_SAMPLE_OVER_POS 
          or BASS_UNICODE);

UPDATE2

Per Sir Rufo's request: I added an exception based error checking routine to make the code cleaner and debugging more straightforward.

function BASS_ErrorToString(BASS_ErrorCode : Integer) : String;

begin

 case BASS_ErrorCode of :
  0: Result := 'BASS_OK';
  1: Result := 'BASS_ERROR_MEM';
  2: Result := 'BASS_ERROR_FILEOPEN';
  3: Result := 'BASS_ERROR_DRIVER';
  4: Result := 'BASS_ERROR_BUFLOST';
  5: Result := 'BASS_ERROR_HANDLE';
  6: Result := 'BASS_ERROR_FORMAT';
  7: Result := 'BASS_ERROR_POSITION';
  8: Result := 'BASS_ERROR_INIT';
  9: Result := 'BASS_ERROR_START';
  14: Result := 'BASS_ERROR_ALREADY';
  18: Result := 'BASS_ERROR_NOCHAN';
  19: Result := 'BASS_ERROR_ILLTYPE';
  20: Result := 'BASS_ERROR_ILLPARAM';
  21: Result := 'BASS_ERROR_NO3D';
  22: Result := 'BASS_ERROR_NOEAX';
  23: Result := 'BASS_ERROR_DEVICE';
  24: Result := 'BASS_ERROR_NOPLAY';
  25: Result := 'BASS_ERROR_FREQ';
  27: Result := 'BASS_ERROR_NOTFILE';
  29: Result := 'BASS_ERROR_NOHW';
  31: Result := 'BASS_ERROR_EMPTY';
  32: Result := 'BASS_ERROR_NONET';
  33: Result := 'BASS_ERROR_CREATE';
  34: Result := 'BASS_ERROR_NOFX';
  37: Result := 'BASS_ERROR_NOTAVAIL';
  38: Result := 'BASS_ERROR_DECODE';
  39: Result := 'BASS_ERROR_DX';
  40: Result := 'BASS_ERROR_TIMEOUT';
  41: Result := 'BASS_ERROR_FILEFORM';
  42: Result := 'BASS_ERROR_SPEAKER';
  43: Result := 'BASS_ERROR_VERSION';
  44: Result := 'BASS_ERROR_CODEC';
  45: Result := 'BASS_ERROR_ENDED';
  46: Result := 'BASS_ERROR_BUSY';
 else
  Result := 'BASS_ERROR_UNKNOWN';
 end;
end;

procedure BassResultCheck(ResultCode : Integer);
begin
 if ResultCode = 0 then
  begin
   ResultCode := BASS_ErrorGetCode;
   raise Exception.CreateFmt('BASS error : %s(%d)', [BASS_ErrorToString(ResultCode), ResultCode]);
  end;
end;

procedure BassBoolCheck(const BoolResult : Boolean);
begin
 BassResultCheck(Integer(BoolResult));
end;

procedure PlaySample(const SampleFilename : String);

var
  Sample : HSAMPLE; 
  Channel: HCHANNEL;


begin 
 if not Dynamic_Bass.Load_BASSDLL('Library/Bass.dll') then
  raise Exception.Create('Could not load BASS DLL');
 // change device to -1 which is the default device
 BassBoolCheck(Dynamic_Bass.BASS_Init(-1,44000,Bass_DEVICE_SPEAKERS,0,nil);
 Sample := BASS_SampleLoad(FALSE, PChar(SampleFilename), 0, 0, 3, BASS_SAMPLE_OVER_POS OR BASS_UNICODE);
 BassResultCheck(Sample);
 Channel := BASS_SampleGetChannel(Sample, False);
 BassResultCheck(Channel);
 BassBoolCheck(BASS_ChannelPlay(Channel, False));
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top