Author Topic: BASSMix and BASSCD  (Read 2235 times)

3delite

  • Posts: 926
BASSMix and BASSCD
« on: 12 Nov '08 - 13:35 »
Hi!

I am extending my BASS CD Ripper Library with resampling function and ripping the whole CD as one file works as expected. But when I try to use it on a per track basis it seems like BASSMix isn't downmixing the CD channel. I want to downmix a 44100Hz CD channel to 22050Hz and the resulting flac file IS 22050Hz but is twice as long and plays back at half speed like it hasn't been downmixed.
Interesting is that the same code when set to output 22050Hz WAV file (the same mixer channel is used) works as it should. It only affects the BASSEnc encoding set on the channel. The command line is ok, the parameters are ok, but still it looks like it hasn't been downmixed.

Here's the code:

Code: [Select]
function TBASSCDRipper.RippTrack(DriveNumber, TrackNumber: Integer; SaveFileName: String): Boolean;
var
  CDChannel, MixerChannel: Cardinal;
  Index: Integer;
begin
    if Resample then begin
        MixerChannel := BASS_Mixer_StreamCreate(ResampleFreq, ResampleChannels, ResampleFlags OR BASS_MIXER_END OR BASS_STREAM_DECODE);
    end;

    CDChannel := BASS_CD_StreamCreate(DriveNumber, TrackNumber, BASS_STREAM_DECODE);

    if CDChannel = 0 then begin
        LastError := BASS_ErrorGetCode;
        Exit;
    end;

    if Resample then begin
        BASS_Mixer_StreamAddChannel(MixerChannel, CDChannel, BASS_MIXER_DOWNMIX OR BASS_MIXER_FILTER OR BASS_MIXER_NORAMPIN);
        //* Decide format here
        if EncFormat = FORMAT_ENC then begin
            Stream2Enc(SaveFileName, MixerChannel);
        end else begin
            Stream2Wav(SaveFileName, MixerChannel);
        end;
        BASS_StreamFree(MixerChannel);
    end else begin
        //* Decide format here
        if EncFormat = FORMAT_ENC then begin
            Stream2Enc(SaveFileName, CDChannel);
        end else begin
            Stream2Wav(SaveFileName, CDChannel);
        end;
    end;
    Result := True;
end;

function TBASSCDRipper.Stream2Enc(SaveFileName: String; BASS_Channel: Cardinal): Boolean;
var
  Tmp: Integer;
  buf : array [0..10242] of DWORD;
  PercentDone: Integer;
  BytesRead, PresetIndex: integer;
  temp, lsCmd: string;
  i : longint;
  Flags: Cardinal;
begin
    Result := False;
    lsCmd := EncCmdLine;
    lsCmd := ANSIReplaceStr(lsCmd, '{o}', SaveFileName);
    if SAMPLE_FLOAT
        then Flags := BASS_ENCODE_FP_16BIT
        else Flags := 0;

    Flags := Flags OR BASS_ENCODE_NOHEAD;

    RipExtEnc := BASS_Encode_Start(BASS_Channel, PChar(lsCmd), Flags, nil, 0);

    if (RipExtEnc = 0) then begin
        LastError := ERROR_STARTINGENCODINGREC;
        Exit;
    end;

    //* Set encoder priority
    SetPriorityClass(RipExtEnc, EncoderPriority);

    BytesRead := 1024 * 10; // 10kBytes
    while (BASS_ChannelIsActive(BASS_Channel) > 0) do begin
    BASS_ChannelGetData(BASS_Channel, @buf, BytesRead);
        Application.ProcessMessages;
        if StopRipp
        then Break;
        PercentDone := Round(100 * (BASS_ChannelGetPosition(BASS_Channel, BASS_POS_BYTE) / BASS_CD_GetTrackLength(Drive, Counter)));
        if Assigned(OnProgress)
            then OnProgress(Pointer(Self), PercentDone, Round(Counter / TrackCount * 100));
    end;
    BASS_Encode_Stop(BASS_Channel);
    RipExtEnc := 0;
    Result := True;
end;

Here's the project (for Ian if no clue) to test it for debugging: BASS CD Ripper Tester.zip
  • Copy flac.exe to C:\
  • Uncheck Album mode
  • Check Resample
  • Set the command line to 22050
  • Click Ripp disc with command line encoder

???

Any help would be appreciated.

3delite
« Last Edit: 12 Nov '08 - 14:07 by 3delite »

3delite

  • Posts: 926
Re: BASSMix and BASSCD
« Reply #1 on: 12 Nov '08 - 14:06 »
Cancel, now it's working...  ??? Don't know how can that be...

But got another problem: Is it the same to call BASS_CD_GetTrackLength() and BASS_ChannelGetLength() with a CD channel?

And one more: Calling BASS_ChannelGetLength() for a mixer channel? Can that be acomplished? I mean how to get the total length for a mixer channel?

I want to put a progress on the form, how can that be done with a mixer channel?  :)

3delite
« Last Edit: 12 Nov '08 - 14:19 by 3delite »

Ian @ un4seen

  • Administrator
  • Posts: 21136
Re: BASSMix and BASSCD
« Reply #2 on: 12 Nov '08 - 14:45 »
Is it the same to call BASS_CD_GetTrackLength() and BASS_ChannelGetLength() with a CD channel?

It is the same if the stream is 16-bit and doesn't include sub-channel data, ie. you don't use the FLOAT or SUBCHANNEL flags.

And one more: Calling BASS_ChannelGetLength() for a mixer channel? Can that be acomplished? I mean how to get the total length for a mixer channel?

No, I'm afraid it's not possible to get the length of a mixer as they do not have a predetermined length, eg. sources can be added/removed/seeked/looped at any time in the mixer's lifetime. But if you know exactly what and when you will be feeding to the mixer, you could calculate the length yourself from that information :)

3delite

  • Posts: 926
Re: BASSMix and BASSCD
« Reply #3 on: 12 Nov '08 - 15:12 »
Thanx! The mixer is like never ending you don't know the length. I understand that. I was thinking about that, what you said. So I have to add all the CD track lengths for getting the total length.
Ok!

Thanx again.

I am still stucked. I can get the position for the mixer stream with BASS_Mixer_ChannelGetPosition() right? And I need to devide that with the length * 100. But how can I get a proper position AND length for that? :)
If I add the BASS_CD_GetTrackLength() values that won't match with a mixer stream position format. :)

3delite
« Last Edit: 12 Nov '08 - 15:28 by 3delite »

3delite

  • Posts: 926
Re: BASSMix and BASSCD
« Reply #4 on: 12 Nov '08 - 15:40 »
So it should be something like this:

Code: [Select]
        if Resample then begin
            PercentDone := Round(100 * (BASS_ChannelGetPosition(BASS_Channel, BASS_POS_BYTE) / BASS_CD_GetTrackLength(Drive, Counter)));
            PercentDone := Round((PercentDone * (44100 / ResampleFreq)) * (2 / ResampleChannels));
        end else begin
            PercentDone := Round(100 * (BASS_ChannelGetPosition(BASS_Channel, BASS_POS_BYTE) / BASS_CD_GetTrackLength(Drive, Counter)));
        end;

But now I have another weird problem. :)
If I set to resample to 11025Hz the resulting flac file is 0 bytes length. How that??? :)

EDIT: I see, that does not conform to flac standards...

3delite
« Last Edit: 7 Dec '08 - 03:26 by 3delite »