Beispiel #1
0
    // Get the current sample index position, or -1 if unknown

    internal static long WavpackGetSampleIndex(WavpackContext wpc)
    {
        if (null != wpc)
        {
            return(wpc.stream.sample_index);
        }

        return((long)(-1));
    }
Beispiel #2
0
    // Returns the number of bytes used for each sample (1 to 4) in the original
    // file. This is required information for the user of this module because the
    // audio data is returned in the LOWER bytes of the long buffer and must be
    // left-shifted 8, 16, or 24 bits if normalized longs are required.

    internal static int WavpackGetBytesPerSample(WavpackContext wpc)
    {
        if (null != wpc && wpc.config.bytes_per_sample != 0)
        {
            return(wpc.config.bytes_per_sample);
        }
        else
        {
            return(2);
        }
    }
Beispiel #3
0
    // Returns the number of channels of the specified WavPack file. Note that
    // this is the actual number of channels contained in the file, but this
    // version can only decode the first two.

    internal static int WavpackGetNumChannels(WavpackContext wpc)
    {
        if (null != wpc && wpc.config.num_channels != 0)
        {
            return(wpc.config.num_channels);
        }
        else
        {
            return(2);
        }
    }
Beispiel #4
0
    // Returns the sample rate of the specified WavPack file

    internal static long WavpackGetSampleRate(WavpackContext wpc)
    {
        if (null != wpc && wpc.config.sample_rate != 0)
        {
            return(wpc.config.sample_rate);
        }
        else
        {
            return((long)44100);
        }
    }
Beispiel #5
0
    // return if any uncorrected lossy blocks were actually written or read


    internal static int WavpackLossyBlocks(WavpackContext wpc)
    {
        if (null != wpc)
        {
            return(wpc.lossy_blocks);
        }
        else
        {
            return(0);
        }
    }
Beispiel #6
0
    // Get the number of errors encountered so far

    internal static long WavpackGetNumErrors(WavpackContext wpc)
    {
        if (null != wpc)
        {
            return(wpc.crc_errors);
        }
        else
        {
            return((long)0);
        }
    }
Beispiel #7
0
    // The following seek functionality has not yet been extensively tested

    public static void setTime(WavpackContext wpc, long milliseconds)
    {
        long targetSample = (long)(milliseconds / 1000 * wpc.config.sample_rate);

        try
        {
            seek(wpc, wpc.infile, wpc.infile.BaseStream.Position, targetSample);
        }
        catch (System.IO.IOException)
        {
        }
    }
Beispiel #8
0
    // Get total number of samples contained in the WavPack file, or -1 if unknown

    internal static long WavpackGetNumSamples(WavpackContext wpc)
    {
        // -1 would mean an unknown number of samples

        if (null != wpc)
        {
            return(wpc.total_samples);
        }
        else
        {
            return((long)(-1));
        }
    }
Beispiel #9
0
    // This function obtains general information about an open file and returns
    // a mask with the following bit values:

    // MODE_LOSSLESS:  file is lossless (pure lossless only)
    // MODE_HYBRID:  file is hybrid mode (lossy part only)
    // MODE_FLOAT:  audio data is 32-bit ieee floating point (but will provided
    //               in 24-bit integers for convenience)
    // MODE_HIGH:  file was created in "high" mode (information only)
    // MODE_FAST:  file was created in "fast" mode (information only)


    internal static int WavpackGetMode(WavpackContext wpc)
    {
        int mode = 0;

        if (null != wpc)
        {
            if ((wpc.config.flags & Defines.CONFIG_HYBRID_FLAG) != 0)
            {
                mode |= Defines.MODE_HYBRID;
            }
            else if ((wpc.config.flags & Defines.CONFIG_LOSSY_MODE) == 0)
            {
                mode |= Defines.MODE_LOSSLESS;
            }

            if (wpc.lossy_blocks != 0)
            {
                mode &= ~Defines.MODE_LOSSLESS;
            }

            if ((wpc.config.flags & Defines.CONFIG_FLOAT_DATA) != 0)
            {
                mode |= Defines.MODE_FLOAT;
            }

            if ((wpc.config.flags & Defines.CONFIG_HIGH_FLAG) != 0)
            {
                mode |= Defines.MODE_HIGH;
            }

            if ((wpc.config.flags & Defines.CONFIG_FAST_FLAG) != 0)
            {
                mode |= Defines.MODE_FAST;
            }
        }

        return(mode);
    }
Beispiel #10
0
    public static void  Main(System.String[] args)
    {
        ChunkHeader     FormatChunkHeader = new ChunkHeader();
        ChunkHeader     DataChunkHeader   = new ChunkHeader();
        RiffChunkHeader myRiffChunkHeader = new RiffChunkHeader();
        WaveHeader      WaveHeader        = new WaveHeader();

        sbyte[] myRiffChunkHeaderAsByteArray   = new sbyte[12];
        sbyte[] myFormatChunkHeaderAsByteArray = new sbyte[8];
        sbyte[] myWaveHeaderAsByteArray        = new sbyte[16];
        sbyte[] myDataChunkHeaderAsByteArray   = new sbyte[8];

        long           total_unpacked_samples = 0, total_samples; // was uint32_t in C
        int            num_channels, bps;
        WavpackContext wpc = new WavpackContext();

        System.IO.FileStream   fistream;
        System.IO.FileStream   fostream;
        System.IO.BinaryReader in_Renamed;
        long start, end;

        System.String inputWVFile;

        if (args.Length == 0)
        {
            inputWVFile = "input.wv";
        }
        else
        {
            inputWVFile = args[0];
        }

        try
        {
            fistream = new System.IO.FileStream(inputWVFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            System.IO.BufferedStream bstream = new System.IO.BufferedStream(fistream, 16384);
            in_Renamed = new System.IO.BinaryReader(bstream);
            wpc        = WavPackUtils.WavpackOpenFileInput(in_Renamed);
        }
        catch (System.IO.FileNotFoundException)
        {
            System.Console.Error.WriteLine("Input file not found");
            System.Environment.Exit(1);
        }
        catch (System.IO.DirectoryNotFoundException)
        {
            System.Console.Error.WriteLine("Input file not found - invalid directory");
            System.Environment.Exit(1);
        }

        if (wpc.error)
        {
            System.Console.Error.WriteLine("Sorry an error has occured");
            System.Console.Error.WriteLine(wpc.error_message);
            System.Environment.Exit(1);
        }

        num_channels = WavPackUtils.WavpackGetReducedChannels(wpc);

        System.Console.Out.WriteLine("The WavPack file has " + num_channels + " channels");

        total_samples = WavPackUtils.WavpackGetNumSamples(wpc);

        System.Console.Out.WriteLine("The WavPack file has " + total_samples + " samples");

        bps = WavPackUtils.WavpackGetBytesPerSample(wpc);

        System.Console.Out.WriteLine("The WavPack file has " + bps + " bytes per sample");

        myRiffChunkHeader.ckID[0] = 'R';
        myRiffChunkHeader.ckID[1] = 'I';
        myRiffChunkHeader.ckID[2] = 'F';
        myRiffChunkHeader.ckID[3] = 'F';

        myRiffChunkHeader.ckSize      = total_samples * num_channels * bps + 8 * 2 + 16 + 4;
        myRiffChunkHeader.formType[0] = 'W';
        myRiffChunkHeader.formType[1] = 'A';
        myRiffChunkHeader.formType[2] = 'V';
        myRiffChunkHeader.formType[3] = 'E';

        FormatChunkHeader.ckID[0] = 'f';
        FormatChunkHeader.ckID[1] = 'm';
        FormatChunkHeader.ckID[2] = 't';
        FormatChunkHeader.ckID[3] = ' ';

        FormatChunkHeader.ckSize = 16;

        WaveHeader.FormatTag      = 1;
        WaveHeader.NumChannels    = num_channels;
        WaveHeader.SampleRate     = WavPackUtils.WavpackGetSampleRate(wpc);
        WaveHeader.BlockAlign     = num_channels * bps;
        WaveHeader.BytesPerSecond = WaveHeader.SampleRate * WaveHeader.BlockAlign;
        WaveHeader.BitsPerSample  = WavPackUtils.WavpackGetBitsPerSample(wpc);

        DataChunkHeader.ckID[0] = 'd';
        DataChunkHeader.ckID[1] = 'a';
        DataChunkHeader.ckID[2] = 't';
        DataChunkHeader.ckID[3] = 'a';
        DataChunkHeader.ckSize  = total_samples * num_channels * bps;

        myRiffChunkHeaderAsByteArray[0] = (sbyte)myRiffChunkHeader.ckID[0];
        myRiffChunkHeaderAsByteArray[1] = (sbyte)myRiffChunkHeader.ckID[1];
        myRiffChunkHeaderAsByteArray[2] = (sbyte)myRiffChunkHeader.ckID[2];
        myRiffChunkHeaderAsByteArray[3] = (sbyte)myRiffChunkHeader.ckID[3];

        // swap endians here

        myRiffChunkHeaderAsByteArray[7] = (sbyte)(SupportClass.URShift(myRiffChunkHeader.ckSize, 24));
        myRiffChunkHeaderAsByteArray[6] = (sbyte)(SupportClass.URShift(myRiffChunkHeader.ckSize, 16));
        myRiffChunkHeaderAsByteArray[5] = (sbyte)(SupportClass.URShift(myRiffChunkHeader.ckSize, 8));
        myRiffChunkHeaderAsByteArray[4] = (sbyte)(myRiffChunkHeader.ckSize);

        myRiffChunkHeaderAsByteArray[8]  = (sbyte)myRiffChunkHeader.formType[0];
        myRiffChunkHeaderAsByteArray[9]  = (sbyte)myRiffChunkHeader.formType[1];
        myRiffChunkHeaderAsByteArray[10] = (sbyte)myRiffChunkHeader.formType[2];
        myRiffChunkHeaderAsByteArray[11] = (sbyte)myRiffChunkHeader.formType[3];

        myFormatChunkHeaderAsByteArray[0] = (sbyte)FormatChunkHeader.ckID[0];
        myFormatChunkHeaderAsByteArray[1] = (sbyte)FormatChunkHeader.ckID[1];
        myFormatChunkHeaderAsByteArray[2] = (sbyte)FormatChunkHeader.ckID[2];
        myFormatChunkHeaderAsByteArray[3] = (sbyte)FormatChunkHeader.ckID[3];

        // swap endians here
        myFormatChunkHeaderAsByteArray[7] = (sbyte)(SupportClass.URShift(FormatChunkHeader.ckSize, 24));
        myFormatChunkHeaderAsByteArray[6] = (sbyte)(SupportClass.URShift(FormatChunkHeader.ckSize, 16));
        myFormatChunkHeaderAsByteArray[5] = (sbyte)(SupportClass.URShift(FormatChunkHeader.ckSize, 8));
        myFormatChunkHeaderAsByteArray[4] = (sbyte)(FormatChunkHeader.ckSize);

        // swap endians
        myWaveHeaderAsByteArray[1] = (sbyte)(SupportClass.URShift(WaveHeader.FormatTag, 8));
        myWaveHeaderAsByteArray[0] = (sbyte)(WaveHeader.FormatTag);

        // swap endians
        myWaveHeaderAsByteArray[3] = (sbyte)(SupportClass.URShift(WaveHeader.NumChannels, 8));
        myWaveHeaderAsByteArray[2] = (sbyte)WaveHeader.NumChannels;


        // swap endians
        myWaveHeaderAsByteArray[7] = (sbyte)(SupportClass.URShift(WaveHeader.SampleRate, 24));
        myWaveHeaderAsByteArray[6] = (sbyte)(SupportClass.URShift(WaveHeader.SampleRate, 16));
        myWaveHeaderAsByteArray[5] = (sbyte)(SupportClass.URShift(WaveHeader.SampleRate, 8));
        myWaveHeaderAsByteArray[4] = (sbyte)(WaveHeader.SampleRate);

        // swap endians

        myWaveHeaderAsByteArray[11] = (sbyte)(SupportClass.URShift(WaveHeader.BytesPerSecond, 24));
        myWaveHeaderAsByteArray[10] = (sbyte)(SupportClass.URShift(WaveHeader.BytesPerSecond, 16));
        myWaveHeaderAsByteArray[9]  = (sbyte)(SupportClass.URShift(WaveHeader.BytesPerSecond, 8));
        myWaveHeaderAsByteArray[8]  = (sbyte)(WaveHeader.BytesPerSecond);

        // swap endians
        myWaveHeaderAsByteArray[13] = (sbyte)(SupportClass.URShift(WaveHeader.BlockAlign, 8));
        myWaveHeaderAsByteArray[12] = (sbyte)WaveHeader.BlockAlign;

        // swap endians
        myWaveHeaderAsByteArray[15] = (sbyte)(SupportClass.URShift(WaveHeader.BitsPerSample, 8));
        myWaveHeaderAsByteArray[14] = (sbyte)WaveHeader.BitsPerSample;

        myDataChunkHeaderAsByteArray[0] = (sbyte)DataChunkHeader.ckID[0];
        myDataChunkHeaderAsByteArray[1] = (sbyte)DataChunkHeader.ckID[1];
        myDataChunkHeaderAsByteArray[2] = (sbyte)DataChunkHeader.ckID[2];
        myDataChunkHeaderAsByteArray[3] = (sbyte)DataChunkHeader.ckID[3];

        // swap endians

        myDataChunkHeaderAsByteArray[7] = (sbyte)(SupportClass.URShift(DataChunkHeader.ckSize, 24));
        myDataChunkHeaderAsByteArray[6] = (sbyte)(SupportClass.URShift(DataChunkHeader.ckSize, 16));
        myDataChunkHeaderAsByteArray[5] = (sbyte)(SupportClass.URShift(DataChunkHeader.ckSize, 8));
        myDataChunkHeaderAsByteArray[4] = (sbyte)DataChunkHeader.ckSize;

        try
        {
            fostream = new System.IO.FileStream("output.wav", System.IO.FileMode.Create);
            SupportClass.WriteOutput(fostream, myRiffChunkHeaderAsByteArray);
            SupportClass.WriteOutput(fostream, myFormatChunkHeaderAsByteArray);
            SupportClass.WriteOutput(fostream, myWaveHeaderAsByteArray);
            SupportClass.WriteOutput(fostream, myDataChunkHeaderAsByteArray);

            start = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;

            while (true)
            {
                long samples_unpacked;                 // was uint32_t in C

                samples_unpacked = WavPackUtils.WavpackUnpackSamples(wpc, temp_buffer, Defines.SAMPLE_BUFFER_SIZE / num_channels);

                total_unpacked_samples += samples_unpacked;

                if (samples_unpacked > 0)
                {
                    samples_unpacked = samples_unpacked * num_channels;

                    pcm_buffer = format_samples(bps, temp_buffer, samples_unpacked);
                    fostream.Write(pcm_buffer, 0, (int)samples_unpacked * bps);
                }

                if (samples_unpacked == 0)
                {
                    break;
                }
            }             // end of while

            end = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;

            System.Console.Out.WriteLine(end - start + " milli seconds to process WavPack file in main loop");
        }
        catch (System.Exception e)
        {
            System.Console.Error.WriteLine("Error when writing wav file, sorry: ");
            SupportClass.WriteStackTrace(e, Console.Error);
            System.Environment.Exit(1);
        }

        if ((WavPackUtils.WavpackGetNumSamples(wpc) != -1) && (total_unpacked_samples != WavPackUtils.WavpackGetNumSamples(wpc)))
        {
            System.Console.Error.WriteLine("Incorrect number of samples");
            System.Environment.Exit(1);
        }

        if (WavPackUtils.WavpackGetNumErrors(wpc) > 0)
        {
            System.Console.Error.WriteLine("CRC errors detected");
            System.Environment.Exit(1);
        }

        System.Environment.Exit(0);
    }
Beispiel #11
0
    // Find the WavPack block that contains the specified sample. If "header_pos"
    // is zero, then no information is assumed except the total number of samples
    // in the file and its size in bytes. If "header_pos" is non-zero then we
    // assume that it is the file position of the valid header image contained in
    // the first stream and we can limit our search to either the portion above
    // or below that point. If a .wvc file is being used, then this must be called
    // for that file also.
    private static void seek(WavpackContext wpc, System.IO.BinaryReader infile, long headerPos, long targetSample)
    {
        try
        {
            WavpackStream wps = wpc.stream;
            long          file_pos1 = 0;
            long          file_pos2 = wpc.infile.BaseStream.Length;
            long          sample_pos1 = 0, sample_pos2 = wpc.total_samples;
            double        ratio     = 0.96;
            int           file_skip = 0;
            if (targetSample >= wpc.total_samples)
            {
                return;
            }
            if (headerPos > 0 && wps.wphdr.block_samples > 0)
            {
                if (wps.wphdr.block_index > targetSample)
                {
                    sample_pos2 = wps.wphdr.block_index;
                    file_pos2   = headerPos;
                }
                else if (wps.wphdr.block_index + wps.wphdr.block_samples <= targetSample)
                {
                    sample_pos1 = wps.wphdr.block_index;
                    file_pos1   = headerPos;
                }
                else
                {
                    return;
                }
            }
            while (true)
            {
                double bytes_per_sample;
                long   seek_pos;
                bytes_per_sample  = file_pos2 - file_pos1;
                bytes_per_sample /= sample_pos2 - sample_pos1;
                seek_pos          = file_pos1 + (file_skip > 0 ? 32 : 0);
                seek_pos         += (long)(bytes_per_sample * (targetSample - sample_pos1) * ratio);
                infile.BaseStream.Seek(seek_pos, 0);

                long temppos = infile.BaseStream.Position;
                wps.wphdr = read_next_header(infile, wps.wphdr);

                if (wps.wphdr.status == 1 || seek_pos >= file_pos2)
                {
                    if (ratio > 0.0)
                    {
                        if ((ratio -= 0.24) < 0.0)
                        {
                            ratio = 0.0;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                else if (wps.wphdr.block_index > targetSample)
                {
                    sample_pos2 = wps.wphdr.block_index;
                    file_pos2   = seek_pos;
                }
                else if (wps.wphdr.block_index + wps.wphdr.block_samples <= targetSample)
                {
                    if (seek_pos == file_pos1)
                    {
                        file_skip = 1;
                    }
                    else
                    {
                        sample_pos1 = wps.wphdr.block_index;
                        file_pos1   = seek_pos;
                    }
                }
                else
                {
                    int index = (int)(targetSample - wps.wphdr.block_index);
                    infile.BaseStream.Seek(seek_pos, 0);
                    WavpackContext c = WavpackOpenFileInput(infile);
                    wpc.stream = c.stream;
                    int[] temp_buf = new int[Defines.SAMPLE_BUFFER_SIZE];
                    while (index > 0)
                    {
                        int toUnpack = Math.Min(index, Defines.SAMPLE_BUFFER_SIZE / WavpackGetReducedChannels(wpc));
                        WavpackUnpackSamples(wpc, temp_buf, toUnpack);
                        index = index - toUnpack;
                    }
                    return;
                }
            }
        }
        catch (System.IO.IOException)
        {
        }
    }
Beispiel #12
0
 public static void setSample(WavpackContext wpc, long sample)
 {
     seek(wpc, wpc.infile, 0, sample);
 }
Beispiel #13
0
    ///////////////////////////// executable code ////////////////////////////////


    // This function reads data from the specified stream in search of a valid
    // WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or
    // unsupported WavPack block is encountered) then an appropriate message is
    // copied to "error" and NULL is returned, otherwise a pointer to a
    // WavpackContext structure is returned (which is used to call all other
    // functions in this module). This can be initiated at the beginning of a
    // WavPack file, or anywhere inside a WavPack file. To determine the exact
    // position within the file use WavpackGetSampleIndex().  Also,
    // this function will not handle "correction" files, plays only the first
    // two channels of multi-channel files, and is limited in resolution in some
    // large integer or floating point files (but always provides at least 24 bits
    // of resolution).

    public static WavpackContext WavpackOpenFileInput(System.IO.BinaryReader infile)
    {
        WavpackContext wpc = new WavpackContext();
        WavpackStream  wps = wpc.stream;

        wpc.infile        = infile;
        wpc.total_samples = -1;
        wpc.norm_offset   = 0;
        wpc.open_flags    = 0;


        // open the source file for reading and store the size

        while (wps.wphdr.block_samples == 0)
        {
            wps.wphdr = read_next_header(wpc.infile, wps.wphdr);

            if (wps.wphdr.status == 1)
            {
                wpc.error_message = "not compatible with this version of WavPack file!";
                wpc.error         = true;
                return(wpc);
            }

            if (wps.wphdr.block_samples > 0 && wps.wphdr.total_samples != -1)
            {
                wpc.total_samples = wps.wphdr.total_samples;
            }

            // lets put the stream back in the context

            wpc.stream = wps;

            if ((UnpackUtils.unpack_init(wpc)) == Defines.FALSE)
            {
                wpc.error = true;
                return(wpc);
            }
        }         // end of while

        wpc.config.flags = wpc.config.flags & ~0xff;
        wpc.config.flags = wpc.config.flags | (wps.wphdr.flags & 0xff);

        wpc.config.bytes_per_sample = (int)((wps.wphdr.flags & Defines.BYTES_STORED) + 1);
        wpc.config.float_norm_exp   = wps.float_norm_exp;

        wpc.config.bits_per_sample = (int)((wpc.config.bytes_per_sample * 8) - ((wps.wphdr.flags & Defines.SHIFT_MASK) >> Defines.SHIFT_LSB));

        if ((wpc.config.flags & Defines.FLOAT_DATA) > 0)
        {
            wpc.config.bytes_per_sample = 3;
            wpc.config.bits_per_sample  = 24;
        }

        if (wpc.config.sample_rate == 0)
        {
            if (wps.wphdr.block_samples == 0 || (wps.wphdr.flags & Defines.SRATE_MASK) == Defines.SRATE_MASK)
            {
                wpc.config.sample_rate = 44100;
            }
            else
            {
                wpc.config.sample_rate = sample_rates[(int)((wps.wphdr.flags & Defines.SRATE_MASK) >> Defines.SRATE_LSB)];
            }
        }

        if (wpc.config.num_channels == 0)
        {
            if ((wps.wphdr.flags & Defines.MONO_FLAG) > 0)
            {
                wpc.config.num_channels = 1;
            }
            else
            {
                wpc.config.num_channels = 2;
            }

            wpc.config.channel_mask = 0x5 - wpc.config.num_channels;
        }

        if ((wps.wphdr.flags & Defines.FINAL_BLOCK) == 0)
        {
            if ((wps.wphdr.flags & Defines.MONO_FLAG) != 0)
            {
                wpc.reduced_channels = 1;
            }
            else
            {
                wpc.reduced_channels = 2;
            }
        }

        return(wpc);
    }
Beispiel #14
0
    // Unpack the specified number of samples from the current file position.
    // Note that "samples" here refers to "complete" samples, which would be
    // 2 longs for stereo files. The audio data is returned right-justified in
    // 32-bit longs in the endian mode native to the executing processor. So,
    // if the original data was 16-bit, then the values returned would be
    // +/-32k. Floating point data will be returned as 24-bit integers (and may
    // also be clipped). The actual number of samples unpacked is returned,
    // which should be equal to the number requested unless the end of fle is
    // encountered or an error occurs.

    internal static long WavpackUnpackSamples(WavpackContext wpc, int[] buffer, long samples)
    {
        WavpackStream wps = wpc.stream;
        long          samples_unpacked = 0, samples_to_unpack;
        int           num_channels = wpc.config.num_channels;
        int           bcounter     = 0;

        int buf_idx        = 0;
        int bytes_returned = 0;

        while (samples > 0)
        {
            if (wps.wphdr.block_samples == 0 || (wps.wphdr.flags & Defines.INITIAL_BLOCK) == 0 || wps.sample_index >= wps.wphdr.block_index + wps.wphdr.block_samples)
            {
                wps.wphdr = read_next_header(wpc.infile, wps.wphdr);

                if (wps.wphdr.status == 1)
                {
                    break;
                }

                if (wps.wphdr.block_samples == 0 || wps.sample_index == wps.wphdr.block_index)
                {
                    if ((UnpackUtils.unpack_init(wpc)) == Defines.FALSE)
                    {
                        break;
                    }
                }
            }

            if (wps.wphdr.block_samples == 0 || (wps.wphdr.flags & Defines.INITIAL_BLOCK) == 0 || wps.sample_index >= wps.wphdr.block_index + wps.wphdr.block_samples)
            {
                continue;
            }

            if (wps.sample_index < wps.wphdr.block_index)
            {
                samples_to_unpack = wps.wphdr.block_index - wps.sample_index;

                if (samples_to_unpack > samples)
                {
                    samples_to_unpack = samples;
                }

                wps.sample_index += samples_to_unpack;
                samples_unpacked += samples_to_unpack;
                samples          -= samples_to_unpack;

                if (wpc.reduced_channels > 0)
                {
                    samples_to_unpack *= wpc.reduced_channels;
                }
                else
                {
                    samples_to_unpack *= num_channels;
                }

                bcounter = buf_idx;

                while (samples_to_unpack > 0)
                {
                    buffer[bcounter] = 0;
                    bcounter++;
                    samples_to_unpack--;
                }
                buf_idx = bcounter;

                continue;
            }

            samples_to_unpack = wps.wphdr.block_index + wps.wphdr.block_samples - wps.sample_index;

            if (samples_to_unpack > samples)
            {
                samples_to_unpack = samples;
            }

            UnpackUtils.unpack_samples(wpc, buffer, samples_to_unpack, buf_idx);

            if (wpc.reduced_channels > 0)
            {
                bytes_returned = (int)(samples_to_unpack * wpc.reduced_channels);
            }
            else
            {
                bytes_returned = (int)(samples_to_unpack * num_channels);
            }

            buf_idx += bytes_returned;

            samples_unpacked += samples_to_unpack;
            samples          -= samples_to_unpack;

            if (wps.sample_index == wps.wphdr.block_index + wps.wphdr.block_samples)
            {
                if (UnpackUtils.check_crc_error(wpc) > 0)
                {
                    wpc.crc_errors++;
                }
            }

            if (wps.sample_index == wpc.total_samples)
            {
                break;
            }
        }

        return(samples_unpacked);
    }
Beispiel #15
0
    internal static int read_metadata_buff(WavpackContext wpc, WavpackMetadata wpmd)
    {
        long  bytes_to_read;
        short tchar;

        if (wpmd.bytecount >= wpc.stream.wphdr.ckSize)
        {
            // we have read all the data in this block
            return(Defines.FALSE);
        }

        try
        {
            wpmd.id = (short)wpc.infile.ReadByte();
            tchar   = (short)wpc.infile.ReadByte();
        }
        catch (System.Exception)
        {
            wpmd.status = 1;
            return(Defines.FALSE);
        }

        wpmd.bytecount += 2;

        wpmd.byte_length = tchar << 1;

        if ((wpmd.id & Defines.ID_LARGE) != 0)
        {
            wpmd.id &= (short)~Defines.ID_LARGE;

            try
            {
                tchar = (short)wpc.infile.ReadByte();
            }
            catch (System.Exception)
            {
                wpmd.status = 1;
                return(Defines.FALSE);
            }

            wpmd.byte_length += ((int)tchar << 9);

            try
            {
                tchar = (short)wpc.infile.ReadByte();
            }
            catch (System.Exception)
            {
                wpmd.status = 1;
                return(Defines.FALSE);
            }

            wpmd.byte_length += ((int)tchar << 17);
            wpmd.bytecount   += 2;
        }

        if ((wpmd.id & Defines.ID_ODD_SIZE) != 0)
        {
            wpmd.id &= (short)~Defines.ID_ODD_SIZE;
            wpmd.byte_length--;
        }

        if (wpmd.byte_length == 0 || wpmd.id == Defines.ID_WV_BITSTREAM)
        {
            wpmd.hasdata = Defines.FALSE;
            return(Defines.TRUE);
        }

        bytes_to_read = wpmd.byte_length + (wpmd.byte_length & 1);

        wpmd.bytecount += bytes_to_read;

        if (bytes_to_read > wpc.read_buffer.Length)
        {
            int bytes_read;
            wpmd.hasdata = Defines.FALSE;

            while (bytes_to_read > wpc.read_buffer.Length)
            {
                try
                {
                    bytes_read = wpc.infile.BaseStream.Read(wpc.read_buffer, 0, wpc.read_buffer.Length);

                    if (bytes_read != wpc.read_buffer.Length)
                    {
                        return(Defines.FALSE);
                    }
                }
                catch (System.Exception)
                {
                    return(Defines.FALSE);
                }
                bytes_to_read -= wpc.read_buffer.Length;
            }
        }
        else
        {
            wpmd.hasdata = Defines.TRUE;
            wpmd.data    = wpc.read_buffer;
        }

        if (bytes_to_read != 0)
        {
            int bytes_read;

            try
            {
                bytes_read = wpc.infile.BaseStream.Read(wpc.read_buffer, 0, (int)bytes_to_read);

                if (bytes_read != (int)bytes_to_read)
                {
                    wpmd.hasdata = Defines.FALSE;
                    return(Defines.FALSE);
                }
            }
            catch (System.Exception)
            {
                wpmd.hasdata = Defines.FALSE;
                return(Defines.FALSE);
            }
        }

        return(Defines.TRUE);
    }
Beispiel #16
0
    internal static int process_metadata(WavpackContext wpc, WavpackMetadata wpmd)
    {
        WavpackStream wps = wpc.stream;

        switch (wpmd.id)
        {
        case Defines.ID_DUMMY:
        {
            return(Defines.TRUE);
        }


        case Defines.ID_DECORR_TERMS:
        {
            return(UnpackUtils.read_decorr_terms(wps, wpmd));
        }


        case Defines.ID_DECORR_WEIGHTS:
        {
            return(UnpackUtils.read_decorr_weights(wps, wpmd));
        }


        case Defines.ID_DECORR_SAMPLES:
        {
            return(UnpackUtils.read_decorr_samples(wps, wpmd));
        }


        case Defines.ID_ENTROPY_VARS:
        {
            return(WordsUtils.read_entropy_vars(wps, wpmd));
        }


        case Defines.ID_HYBRID_PROFILE:
        {
            return(WordsUtils.read_hybrid_profile(wps, wpmd));
        }


        case Defines.ID_FLOAT_INFO:
        {
            return(FloatUtils.read_float_info(wps, wpmd));
        }


        case Defines.ID_INT32_INFO:
        {
            return(UnpackUtils.read_int32_info(wps, wpmd));
        }


        case Defines.ID_CHANNEL_INFO:
        {
            return(UnpackUtils.read_channel_info(wpc, wpmd));
        }


        case Defines.ID_SAMPLE_RATE:
        {
            return(UnpackUtils.read_sample_rate(wpc, wpmd));
        }


        case Defines.ID_CONFIG_BLOCK:
        {
            return(UnpackUtils.read_config_info(wpc, wpmd));
        }


        case Defines.ID_WV_BITSTREAM:
        {
            return(UnpackUtils.init_wv_bitstream(wpc, wpmd));
        }


        case Defines.ID_SHAPING_WEIGHTS:
        case Defines.ID_WVC_BITSTREAM:
        case Defines.ID_WVX_BITSTREAM:
        {
            return(Defines.TRUE);
        }


        default:
        {
            if ((wpmd.id & Defines.ID_OPTIONAL_DATA) != 0)
            {
                return(Defines.TRUE);
            }
            else
            {
                return(Defines.FALSE);
            }
        }
        break;
        }
    }