【问题标题】:Creating flac file or flac stream using BASS dll with Delphi使用 BASS dll 和 Delphi 创建 flac 文件或 flac 流
【发布时间】:2023-03-15 09:44:01
【问题描述】:

我正在使用来自http://www.un4seen.com/ 的 BASS。

我需要从用户在麦克风上讲话创建一个 flac 文件(16 位)或 flac 流。

我在 BASS 源代码中看到了这个演示。 还有一个带有这些功能的 bassenc_flac.dll:

function BASS_Encode_FLAC_Start(handle:DWORD; options:PChar; flags:DWORD; proc:ENCODEPROCEX; user:Pointer): HENCODE; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassencflacdll;
function BASS_Encode_FLAC_StartFile(handle:DWORD; options:PChar; flags:DWORD; filename:PChar): HENCODE; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; external bassencflacdll;

如何更改下一个代码以将音频编码为 flac 文件或流?

来自 RecordTest BASS 演示

(* This is called while recording audio *)
function RecordingCallback(Handle: HRECORD; buffer: Pointer; length: DWORD; user: Pointer): boolean; stdcall;
var level:dword;
begin
    level:=BASS_ChannelGetLevel(Handle);
    // Copy new buffer contents to the memory buffer
    Form1.WaveStream.Write(buffer^, length);
    // Allow recording to continue
    Result := True;
end;

(* Start recording to memory *)
procedure TForm1.StartRecording;
begin
    if ComboBox1.ItemIndex < 0 then Exit;
    if WaveStream.Size > 0 then
    begin   // free old recording
        BASS_StreamFree(chan);
        WaveStream.Clear;
    end;
    // generate header for WAV file
    with WaveHdr do
    begin
        riff := 'RIFF';
        len := 36;
        cWavFmt := 'WAVEfmt ';
        dwHdrLen := 16;
        wFormat := 1;
        wNumChannels := 2;
        dwSampleRate := 44100;
        wBlockAlign := 4;
        dwBytesPerSec := 176400;
        wBitsPerSample := 16;
        cData := 'data';
        dwDataLen := 0;
    end;
    WaveStream.Write(WaveHdr, SizeOf(WAVHDR));
    // start recording @ 44100hz 16-bit stereo
    rchan := BASS_RecordStart(44100, 2, 0, @RecordingCallback, nil);
    if rchan = 0 then
    begin
        MessageDlg('Couldn''t start recording!', mtError, [mbOk], 0);
        WaveStream.Clear;
    end
    else
    begin
        bRecord.Caption := 'Stop';
        bPlay.Enabled := False;
        bSave.Enabled := False;
    end;
end;


(* Stop recording *)
procedure TForm1.StopRecording;
var
    i: integer;
  he:BassEnc.HENCODE;
begin
    BASS_ChannelStop(rchan);
    bRecord.Caption := 'Record';
    // complete the WAV header
    WaveStream.Position := 4;
    i := WaveStream.Size - 8;
    WaveStream.Write(i, 4);
    i := i - $24;
    WaveStream.Position := 40;
    WaveStream.Write(i, 4);
    WaveStream.Position := 0;
    // create a stream from the recorded data
    chan := BASS_StreamCreateFile(True, WaveStream.Memory, 0, WaveStream.Size, 0);
    if chan <> 0 then
    begin
        // enable "Play" & "Save" buttons
        bPlay.Enabled := True;
        bSave.Enabled := True;
    end
    else
        MessageDlg('Error creating stream from recorded data!', mtError, [mbOk], 0);
    if SaveDialog.Execute then
       WaveStream.SaveToFile(SaveDialog.FileName);

end;

【问题讨论】:

  • 你好,路易斯!也许,您应该查看Bass 帮助(如果存在)BASS_Encode_FLAC_StartBASS_Encode_FLAC_StartFile 实际执行的功能。我看不出这些函数与您提供的那段代码之间有任何关系。
  • @Dima 我在 BASS 论坛中没有找到有关如何使用它的示例或更多信息。
  • 当然,有些人已经处理过BassFLAC 编码,但是虽然他们不在这里,但我建议您阅读Bass 库的帮助。我发现了什么(我可以理解Bass 的帮助):调用BASS_Encode_FLAC_Start 函数并指定回调函数。转到此help link 并阅读与FLAC 相关的所有信息。 How to prepare callback-function.
  • 我希望你对Bass库足够熟悉,可以自己做所有的事情,否则这将不是一件容易的事(根据我对那个库的一点经验编写它过去)。
  • 不,我不熟悉 BASS。我只是在使用演示。演示具有回调实现。我需要生成音频文件以发送到谷歌语音识别。

标签: delphi audio encode flac bass


【解决方案1】:

我已更新代码,因为 cmets 显示以前编码器版本的工作不正确。我完全同意这些 cmets。

为了创建 FLAC 的编码器,我们应该去un4seen 网站并下载下一个文件:

  1. BASS 音频库 2.4
  2. BASSFLAC 2.4.4
  3. BASSenc 2.4.14
  4. BASSenc_FLAC 2.4.1.1

浏览这些文件夹并查找下一个文件:

  1. bass.pas
  2. bassenc.pas
  3. bassenc_flac.pas

现在将这些 pas 文件放在一个文件夹中,并通过 Delphi's 选项将其添加到 Library
在这一步创建新项目后,将其保存在单独的文件夹中。
然后浏览 BASS_XXX 文件夹并查找 *.dll 文件。
将它们组合到您保存项目的文件夹中!

现在让我们编写一些代码。

添加到uses 子句bass.pasbassenc.pasbassenc_flac.pas。然后复制如下所示的代码。

  uses ..., BASS, BASSEnc, BASSEnc_FLAC;

  ...

  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;      
  public
    { Public declarations }
    procedure StartEncode(SourceFileName, OutputFileName: String);
    procedure StopEncode;
  end;

...

procedure TForm1.StartEncode(SourceFileName, OutputFileName: String);
var
  PercentDone: Cardinal;
  Buffer: array [0..1024] of Byte;
begin
  Channel := BASS_StreamCreateFile(false, PChar(SourceFileName), 0, 0, BASS_MUSIC_DECODE or BASS_UNICODE);
  BASSEnc_FLAC.BASS_Encode_FLAC_StartFile(Channel, 0, BASS_ENCODE_FP_AUTO or BASS_UNICODE, PChar(OutputFileName));
  while BASS_ChannelIsActive(Channel) > 0 do
  begin
    BASS_ChannelGetData(Channel, @Buffer, 1024);
    PercentDone := Trunc(100 * (BASS_ChannelGetPosition(Channel, BASS_POS_BYTE) / BASS_ChannelGetLength(Channel, BASS_POS_BYTE)));
    ProgressBar1.Position := PercentDone;
  end;
  StopEncode;
end;

procedure TForm1.StopEncode;
begin
  BASS_Encode_Stop(Channel);
  BASS_StreamFree(Channel);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  BASS_Init(-1, 44100, 0, Application.Handle, nil);
  try   
    // Set name of file to convert it to FLAC and save it with output name
    StartEncode('SourceFileName', 'OutputFileName');
  finally
    BASS.BASS_Free;
  end;
end;

一条通知:
实际上,使用以前版本的代码编码的文件的标题不正确(在Notepad.exe 中打开文件时我可以看到它)。更新代码后,我可以看到有效的标题(当然,在记事本中,因为我没有专业的工具来处理音频文件)。
现在你甚至不需要像我之前做的那样将插件添加到BASS。 鉴于此,我认为编码器按预期工作。

【讨论】:

  • 谢谢。你帮我太多了。我用了你的代码。 flac 文件已创建,但是当我将其发送到 Google API 时,我有一个“400 Bad Request”。我怀疑生成的 flac 文件太大。我不知道它是否有效。如果我使用外部工具将wave文件转换为flac,一切正常。
  • 我猜问题在于,虽然上面的代码可以生成 FLAC 支持的音频流并将其保存到文件中,但上面的代码可能不会做的还有保存需要的强制性元数据出现在文件的开头。这可能会导致 Google 拒绝您的文件类型错误。
  • 我强烈建议你在他们的官方网站xiph.org/flac/format.html阅读更多关于 FLAC 文件格式的信息
  • @SilverWarior 如果不存在强制元数据,则 flac 编码器无法正常工作。
  • @SilverWarior,是的,输出文件不是实际的 FLAC 文件。我在记事本中打开了编码文件,它的签名是RIFF,而不是现在的fLaC
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
相关资源
最近更新 更多