2
\$\begingroup\$

I have the following method which basically converts an input audio file to a monophonic FLAC file.

Now I am getting Member has cyclomatic complexity of 21 (105%) message in Visual Studio, while I've taken care of improving it as in the beginning it was longer, now there's not much I can remove from it as it pretty much fulfills my needs.

Should I just ignore this warning ?

private static void Convert(string inputFile, string outputFile, IProgress<double> progress = null)
{
    if (inputFile == null) throw new ArgumentNullException("inputFile");
    if (outputFile == null) throw new ArgumentNullException("outputFile");
    int stream = 0;
    int mixer = 0;
    try
    {
        stream = Bass.BASS_StreamCreateFile(inputFile, 0, 0,
            BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN);
        if (stream == 0) throw new BassException("Could not create stream");
        var info = Bass.BASS_ChannelGetInfo(stream);
        if (info == null) throw new BassException("Could not retrieve stream info");
        var freq = info.freq;
        mixer = BassMix.BASS_Mixer_StreamCreate(freq, 1,
            BASSFlag.BASS_MIXER_END | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE);
        if (mixer == 0) throw new BassException("Could not create mixer");
        bool addChannel = BassMix.BASS_Mixer_StreamAddChannel(mixer, stream, BASSFlag.BASS_MIXER_NORAMPIN);
        if (!addChannel) throw new BassException("Could not add stream to mixer");
        long getLength = Bass.BASS_ChannelGetLength(stream);
        if (getLength == -1) throw new BassException("Could not get channel length");
        var encoder = new EncoderFLAC(mixer)
        {
            Force16Bit = true,
            FLAC_Verify = true,
            OutputFile = outputFile
        };
        if (!encoder.Start(null, IntPtr.Zero, false))
            throw new InvalidOperationException("Could not start encoder");
        const int samples = 65536;
        const int bytes = (samples * sizeof(float)) | (int)BASSData.BASS_DATA_FLOAT;
        var buffer = new float[samples];
        long bytesRead = 0;
        while (Bass.BASS_ChannelIsActive(mixer) == BASSActive.BASS_ACTIVE_PLAYING)
        {
            int getData = Bass.BASS_ChannelGetData(mixer, buffer, bytes);
            bytesRead += getData;
            if (progress != null) progress.Report(1.0d / getLength * bytesRead);
        }
        encoder.Stop();
        if (getLength / sizeof(short) != bytesRead)
            throw new InvalidOperationException("Output length not equal to input length");
    }
    catch (Exception ex)
    {
        throw new InvalidOperationException("Conversion failed", ex);
    }
    finally
    {
        if (stream != 0) Bass.BASS_StreamFree(stream);
        if (mixer != 0) Bass.BASS_StreamFree(mixer);
    }
}
\$\endgroup\$
3
\$\begingroup\$

I think your code would become much simpler and more readable if you encapsulated all the BASS-related functionality from into separate types.

Something like:

class Stream
{
    private readonly int handle;

    // add overload that supports setting offset and lenght, if you need that
    public Stream(string inputFile, BASSFlag flags)
    {
        handle = BASS_StreamCreateFile(inputFile, 0, 0, flags);

        if (handle == 0)
            throw new BassException("Could not create stream");
    }

    public ChannelInfo GetInfo()
    {
        var result = Bass.BASS_ChannelGetInfo(stream);

        if (result == null)
            throw new BassException("Could not retrieve stream info");

        return result;
    }

    // etc.
}

This would simplify the start of your code to just:

Stream stream = new Stream(inputFile,
    BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN);
var info = stream.GetInfo();
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.