Author Topic: Bass and delphi 7 display audio waveform  (Read 115 times)

Andy_Bass

  • Posts: 1
Bass and delphi 7 display audio waveform
« on: 16 Jun '17 - 13:59 »


Before I start, I would like to say that I am old and still using Delphi V7, before everyone starts to laugh I would like to say that I use Delphi for a hobby, creating very basic applications. I enjoy the older more simple things in life.

Recently I wanted to take PCM two channel 16Bit 44khz WAV and display the waveform on screen, so I started by reading the structure from WAV files, parsing the header and chunks, then went to store the data into arrays for playing them back and plotting a waveform from the array data. And the result is horrific, it is more complicated than I imagined.

A guy on another forum suggested I use this Bass library and after some searching I found a Delphi application which works with bass. And for a change it compiles and works right away.

The version is BASS 1.5 Multimedia Library - (c) 1999-2002 Ian Luck. A bit old I know but it is working lovely, a credit to Ian Luck.

The application is an audio player put together in Delphi using the Bass.dll and bass.pas

I have a few pretty basic questions.

1, Can Bass give me the data I need for my waveform. If so, could anyone show me a small bit of code to extract the channel data from memory.

2, Could I also use bass to scrub back and forth in real time. By scrubbing I mean to play audio while moving a cursor back and forth over a region of the audio waveform.

3, I am also wondering if I can associate the playback time with HH:MM:SS:FF style time like in Midi time code.

Welcome any sample code, assistance to use bass with this OOOOOLLLLD Delphi I am use too.

Appreciate any pointers, help, comments but please do not suggest I change the Delphi V7 because I am too old now.

Thanks a Lot

Andy

 


« Last Edit: 16 Jun '17 - 14:30 by Andy_Bass »

Ian @ un4seen

  • Administrator
  • Posts: 20063
Re: Bass and delphi 7 display audio waveform
« Reply #1 on: 16 Jun '17 - 18:02 »
1, Can Bass give me the data I need for my waveform. If so, could anyone show me a small bit of code to extract the channel data from memory.

You can use BASS to get the PCM data by using a "decoding channel", which would be created by using the BASS_STREAM_DECODE flag in a BASS_StreamCreateFile call; you can then use BASS_ChannelGetData on that to get the data. If the file isn't massive, you would probably want to get all of the data into memory in advance, so that you can then just display parts of that without having to seek around and call BASS_ChannelGetData again. You would still need to do the displaying of the data yourself though (or perhaps use a 3rd-party library), as BASS does not do that stuff.

2, Could I also use bass to scrub back and forth in real time. By scrubbing I mean to play audio while moving a cursor back and forth over a region of the audio waveform.

That should be possible. You would call BASS_ChannelSetPosition on the playback stream to change its position, ie. set that according to the cursor position. The position is in bytes, but you can use BASS_ChannelSeconds2Bytes if you want to deal in seconds instead.

Note the playback stream is separate to the decoding channel used to get the PCM data, and wouldn't have the BASS_STREAM_DECODE flag set.

3, I am also wondering if I can associate the playback time with HH:MM:SS:FF style time like in Midi time code.

You can use BASS_ChannelGetPosition to get the playback position in bytes, and then use BASS_ChannelBytes2Seconds to convert it to seconds, which you can then break down into "HH:MM:SS:FF" form.

I'm not a Delphi user myself, so I'm afraid I can't help much with example code, but hopefully this gives you some things to look into.

morknotmindy

  • Posts: 7
Re: Bass and delphi 7 display audio waveform
« Reply #2 on: 19 Jun '17 - 15:44 »
I am a bit of a novice but I have done something similar to what I think you want. Although it doesn't use Ian's suggestion of BASS_ChannelGetData, it does seem to work, at least with mp3s. I actually use Lazarus/FPC, very similar to Delphi.

Code: [Select]
procedure getwavedata;
var
peaklevel:array[1..2] of single;
leftlevel,rightlevel:array[1..400] of integer; //I only want 40 seconds of waveform
x:integer;
chan:HSTREAM;
begin

//BASS has already been initialised with BASS_Init  call

chan:=BASS_StreamCreateFile(false, Pchar('C:\mp3s\myfab.mp3'), 0, 0, BASS_STREAM_PRESCAN or BASS_STREAM_DECODE);

x:=1;
While x <= 400 do
begin
// get left and right levels every 0.1 seconds (your choice). You seem to have a very early version of BASS which may not contain BASS_ChannelGetLevelEx, just BASS_ChannelGetLevel.

If BASS_ChannelGetLevelEx(chan, @peaklevel, 0.1,BASS_LEVEL_STEREO) then
begin
// BASS_ChannelGetLevelEx has max/min. values of about +/-1. For BASS_ChannelGetLevel they are 32768 and 0. See help

leftlevel[x]:= Trunc(100*peaklevel[1]);
rightlevel[x]:= Trunc(100*peaklevel[2]);
inc(x);
end;
end;
end;   


You can then plot the values of the leftlevel and rightlevel arrays onto a bitmap/TImage or similar, for example. Hope this helps.

« Last Edit: 19 Jun '17 - 16:00 by morknotmindy »

Ian @ un4seen

  • Administrator
  • Posts: 20063
Re: Bass and delphi 7 display audio waveform
« Reply #3 on: 19 Jun '17 - 17:00 »
Yep, that is pretty much the same as the CUSTLOOP example (included in the BASS package) does to generate a file's "waveform". The Delphi version hasn't been updated (to use BASS_ChannelGetLevelEx) yet though, so you check the C version instead for the latest stuff.