Author Topic: Truncate the end of an MP3 recording  (Read 194 times)

MikeatBookup

  • Posts: 32
Truncate the end of an MP3 recording
« on: 19 Oct '21 - 02:24 »
My app records short clips of the user's voice.

Each short recording ends with the sound of the user clicking the mouse (as the user presses the button to stop recording.)

Is there a way to truncate the last 300ms of an MP3 recording?

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: Truncate the end of an MP3 recording
« Reply #1 on: 19 Oct '21 - 17:54 »
What you could do is delay the feeding of the recorded sample data to the encoder, and then just drop the final data at the end. You could achieve that by not providing a RECORDPROC callback function (to BASS_RecordStart) and instead using BASS_ChannelGetData periodically to process the recording channel. For example, you could do the following in a worker thread or timer to process the recording:

Code: [Select]
DWORD available = BASS_ChannelGetData(hrecord, NULL, BASS_DATA_AVAILABLE); // get amount of data in recording buffer
while (available > delay) {
BYTE buf[20000]; // processing buffer
int part = min(available - delay, sizeof(buf));
part = BASS_ChannelGetData(hrecord, buf, part); // process the recording
if (part <= 0) break;
available -= part;
}

You can use BASS_ChannelSeconds2Bytes to calculate the "delay" value. For example:

Code: [Select]
delay = BASS_ChannelSeconds2Bytes(hrecord, 0.3); // 300ms

MikeatBookup

  • Posts: 32
Re: Truncate the end of an MP3 recording
« Reply #2 on: 20 Oct '21 - 02:09 »
Thanks.  Your suggestion of BASS_ChannelSeconds2Bytes() got me going.

I have a timer that updates the progress of the audio playback.  What I've done for now is have that timer watch for the very end of the playback. It turns out that the mouse click noise is in the last 100ms.

Code: [Select]
procedure TEbookWindow.MediaPlaybackTimerTimer(Sender: TObject);
var
  thePositionInBytes: Integer;
  theDelayInBytes: Integer;

begin
  thePositionInBytes := BASS_ChannelGetPosition(fBASS_HSTREAM, BASS_POS_BYTE);

  PlaybackTrackbar.Value := thePositionInBytes;

    // This calculates the number of bytes to ignore at the end of the playback to suppress
    // the recorded sound of the mouse being clicked.
  theDelayInBytes := BASS_ChannelSeconds2Bytes(fBASS_HSTREAM, 0.1);

  if (thePositionInBytes >= (fBASSFileSizeInBytes - theDelayInBytes))
    then
      begin
        MediaPlaybackTimer.Enabled := False;
        ExitMultimediaPlaybackMode;
      end;
end;

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: Truncate the end of an MP3 recording
« Reply #3 on: 20 Oct '21 - 15:03 »
If you want to stop the playback early (rather than the recording), a more precise and efficient way to do it is via the BASS_POS_END setting. For example, to stop 100ms early, you could do this:

Code: [Select]
QWORD end = BASS_ChannelGetLength(stream, BASS_POS_BYTE); // get the length
end -= BASS_ChannelSeconds2Bytes(stream, 0.1); // subtract 100ms
BASS_ChannelSetPosition(stream, end, BASS_POS_END); // set that as the end

MikeatBookup

  • Posts: 32
Re: Truncate the end of an MP3 recording
« Reply #4 on: 20 Oct '21 - 15:23 »
That looks like a more elegant solution.

I cannot find the constant BASS_POS_END though. It's not mentioned in the help file for the BASS_ChannelSetPosition topic and it doesn't appear in the Delphi wrapper.

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: Truncate the end of an MP3 recording
« Reply #5 on: 20 Oct '21 - 15:35 »
Check that you have the latest BASS version, as the BASS_POS_END option was introduced in BASS 2.4.16.

MikeatBookup

  • Posts: 32
Re: Truncate the end of an MP3 recording
« Reply #6 on: 20 Oct '21 - 15:40 »
It's reporting version 2.4.16.7.

I'm using the BASS 2.4 Delphi unit provided by TDDung.

Chris

  • Posts: 1989
Re: Truncate the end of an MP3 recording
« Reply #7 on: 20 Oct '21 - 15:48 »
Yes i see that is not added on Github.

just add/insert  it self in the Bass.pas (e.g LineNr 382)

BASS_POS_END            = $10; // trimmed end position

MikeatBookup

  • Posts: 32
Re: Truncate the end of an MP3 recording
« Reply #8 on: 20 Oct '21 - 15:51 »
Yep, I found it in the current version. It's missing from the Firemonkey friendly wrapper from TDDung along with some other constants for the newer BASS_ChannelGetLength/GetPosition/SetPosition modes.

I added it and your approach works much better than my solution. Thanks!

Check that you have the latest BASS version, as the BASS_POS_END option was introduced in BASS 2.4.16.

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: Truncate the end of an MP3 recording
« Reply #9 on: 20 Oct '21 - 15:56 »
Also check that you have the latest documentation (BASS.CHM) as you should see the BASS_POS_END option mentioned in there. The latest documentation can also be viewed online:

   www.un4seen.com/doc/#bass/BASS_ChannelSetPosition.html

TDDung

  • Posts: 33
Re: Truncate the end of an MP3 recording
« Reply #10 on: 26 Oct '21 - 21:28 »
Thank you Chris  :)

Yes i see that is not added on Github.

just add/insert  it self in the Bass.pas (e.g LineNr 382)

BASS_POS_END            = $10; // trimmed end position