Я правильно загружаю эту музыку с Bass.dll?
Основываясь на документации Басса, я пытаюсь загрузить файл 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. В соответствии с документацией это ошибка обработки, что означает, что ошибка находится в music
вар. Если я прокомментирую строки ниже BASS_SampleLoad
Я получаю ошибку 2. Означает, что файл не может быть загружен. Так что это обычный файл OGG. Итак, мой вопрос: я делаю что-то не так?
Заранее спасибо.
1 ответ
Ваш код кажется правильным, просто убедитесь, что вы проверяете наличие ошибок при каждом вызове.
Фиксированный код:
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);
UPDATE2
По просьбе сэра Руфо: я добавил подпрограмму проверки ошибок на основе исключений, чтобы сделать код чище и отладить проще.
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;