-5

根据 Bass 的文档,我正在尝试使用以下代码加载 ogg 文件:

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返回 5。根据文档,这是处理错误,这意味着错误在musicvar 中。如果我评论下面的行,BASS_SampleLoad我会收到错误 2。意味着无法加载文件。所以它是一个普通的OGG文件。所以我的问题是:我做错了什么吗?

提前致谢。

4

1 回答 1

8

您的代码似乎是正确的,只需确保在每次调用时检查错误即可。

固定代码:

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;

更新

我应该早点看到这一点,您的代码失败是因为BASS_SampleLoad需要 ANSI 格式的文件名,文档清楚地提到了这一点,因为您有 Delphi XE3 并且字符串是 Unicode,您必须提供BASS_UNICODE标志来指示这一点。

所以这Bass_SampleLoad条线变成:

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

更新2

根据 Rufo 爵士的要求:我添加了一个基于异常的错误检查例程,以使代码更清晰,调试更直接。

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;
于 2014-02-20T21:56:23.390 回答