Author Topic: bassflac.dll bug  (Read 259 times)

Wishmaster

  • Posts: 162
bassflac.dll bug
« on: 5 Feb '18 - 07:00 »

as mentioned in the title, I think that the bassflac.dll has a bug.

when I load a 8 BitPerSample *.flac file with BASS_SAMPLE_FLOAT and BASS_STREAM_DECODE  flags the sound gets distorted.
and when I remove the  bassflac.dll completely or just remove BASS_SAMPLE_FLOAT the file plays fine.

I also tried it with an 8 Bit wave file and it plays fine. so it looks like it's the bassflac.dll


bass.dll v2.4.13.7
bassflac.dll v2.4.4.0

encoder
libFLAC.dll




Code: [Select]
     Flags[1]:= 0;
     Flags[1]:= Flags[1] or
                BASS_STREAM_DECODE or
                BASS_SAMPLE_FLOAT or           <<----------------------------------------------
                BASS_UNICODE;

     FChannel[PLAYER_CHANNEL_SOURCE]:= BASS_StreamCreateFile(false, PWideChar(Src), 0, 0, Flags[1]);

         (* Create Mixer FChannel *)
         Flags[3]:= 0;
         Flags[3]:= Flags[3] or
                         BASS_MIXER_RESUME or
                         BASS_MIXER_POSEX;  (* Keep a record of the source positions *)
                       if IsFloatable then
                        Flags[3]:= Flags[3] or BASS_SAMPLE_FLOAT;  (* Use 32-bit floating-point sample data *)

         FChannel[PLAYER_CHANNEL_MIXER]:= BASS_Mixer_StreamCreate(FFrequency, FChannels, Flags[3]);
       
        .....
       
        BASS_ChannelPlay(FChannel[PLAYER_CHANNEL_MIXER], false);


I've also have  two functions, the first function gives me a negative result the other one gives me a positive result! ??? 

Code: [Select]
function IsFloatable() : boolean;                     
var Floatable : DWORD;
begin
  Floatable:= BASS_GetConfig(BASS_CONFIG_FLOAT);
 if Floatable = DW_ERROR then
  Result:= False
 else
  Result:= true;
end;


Code: [Select]
function IsFloatable() : boolean;                   
var Floatable : DWORD;
begin
  Floatable:= BASS_StreamCreate(44100, 1, BASS_SAMPLE_FLOAT, nil, nil);
 if Floatable = DW_ERROR then
  Result:= false
 else
  Result:= true;
 BASS_StreamFree(Floatable);
end;



 

Ian @ un4seen

  • Administrator
  • Posts: 20616
Re: bassflac.dll bug
« Reply #1 on: 5 Feb '18 - 13:45 »
as mentioned in the title, I think that the bassflac.dll has a bug.

when I load a 8 BitPerSample *.flac file with BASS_SAMPLE_FLOAT and BASS_STREAM_DECODE  flags the sound gets distorted.
and when I remove the  bassflac.dll completely or just remove BASS_SAMPLE_FLOAT the file plays fine.

I also tried it with an 8 Bit wave file and it plays fine. so it looks like it's the bassflac.dll

I don't seem to be able to reproduce that, so please upload an affected FLAC file to have a look at here:

   ftp.un4seen.com/incoming/

Also confirm how the FLAC file was created.

I've also have  two functions, the first function gives me a negative result the other one gives me a positive result! ??? 

Code: [Select]
function IsFloatable() : boolean;                     
var Floatable : DWORD;
begin
  Floatable:= BASS_GetConfig(BASS_CONFIG_FLOAT);
 if Floatable = DW_ERROR then
  Result:= False
 else
  Result:= true;
end;


You should check for 0 instead of -1 (DW_ERROR), like this:

Code: [Select]
...
 if Floatable = 0 then
  Result:= False
 else
  Result:= true;
...

That will work for platforms that have the BASS_CONFIG_FLOAT option and those that don't.

Wishmaster

  • Posts: 162
Re: bassflac.dll bug
« Reply #2 on: 5 Feb '18 - 23:31 »

upps my mistake with IsFloatable.


I uploaded a *.flac file (Recording 8bit)


Ian @ un4seen

  • Administrator
  • Posts: 20616
Re: bassflac.dll bug
« Reply #3 on: 6 Feb '18 - 17:56 »
For some reason the FLAC decoder is producing samples that are out of 8-bit range for that file. It is fine when the data is played in 8-bit as higher bits will be ignored then, but they currently aren't ignored when the data is played in floating-point. I'm not sure if it's an encoder or decoder bug. When I re-encode the file using the reference FLAC encoder, the problem does not happen, so I'm leaning towards it being a bug in the encoder (Sound Recorder?) that was used to create the FLAC file. The re-encoded file is also a lot smaller (1.19MB vs 2.91MB). Anyway, I will look into a workaround.

Wishmaster

  • Posts: 162
Re: bassflac.dll bug
« Reply #4 on: 6 Feb '18 - 23:34 »
Thank you very much Ian for looking into it.

I know that you are not a delphi user but if you want you can have a look on how i convert the data and encode to flac.
so i uploaded a zip file (Flac Encode delphi) 
« Last Edit: 8 Feb '18 - 07:53 by Wishmaster »

Ian @ un4seen

  • Administrator
  • Posts: 20616
Re: bassflac.dll bug
« Reply #5 on: 7 Feb '18 - 17:36 »
I think there may be a bug in this line in the TBitrateConverter.Convert_Bitrate function:

Code: [Select]
          br8BitInteger  : for i := 0 to NumSamples -1 do  Buf8^[i]  := Clip_8(Round(Buf32^[i] * 256)) + 128;

It should probably look like this:

Code: [Select]
          br8BitInteger  : for i := 0 to NumSamples -1 do  Buf8^[i]  := Clip_8(Round(Buf32^[i] * 128)) + 128;

Wishmaster

  • Posts: 162
Re: bassflac.dll bug
« Reply #6 on: 8 Feb '18 - 07:52 »
actually i tried that already. see this topic http://www.un4seen.com/forum/?topic=11355.msg81125#msg81125
so my code should be right.

Code: [Select]
  for I := 0 to (length div (32 div 8)) do
    begin
      dst[i] := Clip_8(Round(src[i] * 256)) + 128;
    end;

I think it would be useful to have a function like that in bass. I mean something like my BitrateConverter.



Ian @ un4seen

  • Administrator
  • Posts: 20616
Re: bassflac.dll bug
« Reply #7 on: 8 Feb '18 - 15:28 »
Your original code in that other thread had +127, but it should be +128. *256 is definitely incorrect; that will give you a range of +/-256 for +/-1.0 floating-point data, when it should be +/-128.

You could also try changing "TBuffer8" to use "Byte" instead of "ShortInt" (BitrateConverter.Process is giving unsigned 8-bit data) in ENCFLAC.PAS, and then change this:

Code: [Select]
              FB[I] := FBuffer[I] xor 128;

To this:

Code: [Select]
              FB[I] := FBuffer[I] - 128;

Regarding having BASS handle the conversion, if you use BASS_Encode_Start (or BASS_Encode_FLAC_Start) to encode floating-point data, you can use the BASS_ENCODE_FP_8BIT flag to have the data converted to 8-bit first.

Wishmaster

  • Posts: 162
Re: bassflac.dll bug
« Reply #8 on: 12 Feb '18 - 05:35 »
actually the code below was your idea, but -128  is working
Code: [Select]
FB[I] := FBuffer[I] xor 128;
I also changed ShortInt to Byte

at the moment I don't use BASS_Encode_xxx, I asked you a long time ago if you plan to create any bass encoder
and you told me that there are no plans for that. so i started to translate the header of all the encoder out there
like LibFLAC,  LibLame, ...   and implement them myself

and as for the "BitrateConverter" function, it's for converting data and feed it to a third party encoder like LibFLAC.dll
in my case i already have this function ;)



Having said that

thanks for a awesome support.