Exemplo n.º 1
0
        /// <summary>Decodes a Speex file to PCM.</summary>
        /// <remarks>Decodes a Speex file to PCM.</remarks>
        /// <param name="srcPath"></param>
        /// <param name="destPath"></param>
        /// <exception>IOException</exception>
        /// <exception cref="System.IO.IOException"></exception>
        public virtual void decode(java.io.RandomInputStream srcPath, java.io.RandomOutputStream destPath)
        {
            byte[] header = new byte[2048];
            byte[] payload = new byte[65536];
            byte[] decdat = new byte[44100 * 2 * 2];
            int WAV_HEADERSIZE = 8;
            short WAVE_FORMAT_SPEEX = (short)unchecked((short)(0xa109));
            string RIFF = "RIFF";
            string WAVE = "WAVE";
            string FORMAT = "fmt ";
            string DATA = "data";
            int OGG_HEADERSIZE = 27;
            int OGG_SEGOFFSET = 26;
            string OGGID = "OggS";
            int segments = 0;
            int curseg = 0;
            int bodybytes = 0;
            int decsize = 0;
            int packetNo = 0;
            // Display info
            if (printlevel <= INFO)
            {
                version();
            }
            if (printlevel <= DEBUG)
            {
                System.Console.WriteLine(string.Empty);
            }
            if (printlevel <= DEBUG)
            {
                System.Console.WriteLine("Input File: " + srcPath);
            }
            // construct a new decoder
            speexDecoder = new org.xiph.speex.SpeexDecoder();
            // open the input stream
            java.io.DataInputStream dis = new java.io.DataInputStream((srcPath));
            org.xiph.speex.AudioFileWriter writer = null;
            int origchksum;
            int chksum;
            try
            {
                // read until we get to EOF
                while (true)
                {
                    if (srcFormat == FILE_FORMAT_OGG)
                    {
                        // read the OGG header
                        dis.readFully(header, 0, OGG_HEADERSIZE);
                        origchksum = readInt(header, 22);
                        header[22] = 0;
                        header[23] = 0;
                        header[24] = 0;
                        header[25] = 0;
                        chksum = org.xiph.speex.OggCrc.checksum(0, header, 0, OGG_HEADERSIZE);
                        // make sure its a OGG header
                        if (!OGGID.Equals(cspeex.StringUtil.getStringForBytes(header, 0, 4)))
                        {
                            System.Console.Error.WriteLine("missing ogg id!");
                            return;
                        }
                        segments = header[OGG_SEGOFFSET] & unchecked((int)(0xFF));
                        dis.readFully(header, OGG_HEADERSIZE, segments);
                        chksum = org.xiph.speex.OggCrc.checksum(chksum, header, OGG_HEADERSIZE, segments);
                        for (curseg = 0; curseg < segments; curseg++)
                        {
                            bodybytes = header[OGG_HEADERSIZE + curseg] & unchecked((int)(0xFF));
                            if (bodybytes == 255)
                            {
                                System.Console.Error.WriteLine("sorry, don't handle 255 sizes!");
                                return;
                            }
                            dis.readFully(payload, 0, bodybytes);
                            chksum = org.xiph.speex.OggCrc.checksum(chksum, payload, 0, bodybytes);
                            if (packetNo == 0)
                            {
                                if (readSpeexHeader(payload, 0, bodybytes))
                                {
                                    if (printlevel <= DEBUG)
                                    {
                                        System.Console.WriteLine("File Format: Ogg Speex");
                                        System.Console.WriteLine("Sample Rate: " + sampleRate);
                                        System.Console.WriteLine("Channels: " + channels);
                                        System.Console.WriteLine("Encoder mode: " + (mode == 0 ? "Narrowband" : (mode
                                             == 1 ? "Wideband" : "UltraWideband")));
                                        System.Console.WriteLine("Frames per packet: " + nframes);
                                    }
                                    if (destFormat == FILE_FORMAT_WAVE)
                                    {
                                        writer = new org.xiph.speex.PcmWaveWriter(speexDecoder.getSampleRate(), speexDecoder
                                            .getChannels());
                                        if (printlevel <= DEBUG)
                                        {
                                            System.Console.WriteLine(string.Empty);
                                            System.Console.WriteLine("Output File: " + destPath);
                                            System.Console.WriteLine("File Format: PCM Wave");
                                            System.Console.WriteLine("Perceptual Enhancement: " + enhanced);
                                        }
                                    }
                                    else
                                    {
                                        writer = new org.xiph.speex.RawWriter();
                                        if (printlevel <= DEBUG)
                                        {
                                            System.Console.WriteLine(string.Empty);
                                            System.Console.WriteLine("Output File: " + destPath);
                                            System.Console.WriteLine("File Format: Raw Audio");
                                            System.Console.WriteLine("Perceptual Enhancement: " + enhanced);
                                        }
                                    }
                                    writer.open(destPath);
                                    writer.writeHeader(null);
                                    packetNo++;
                                }
                                else
                                {
                                    packetNo = 0;
                                }
                            }
                            else
                            {
                                if (packetNo == 1)
                                {
                                    // Ogg Comment packet
                                    packetNo++;
                                }
                                else
                                {
                                    if (loss > 0 && random.nextInt(100) < loss)
                                    {
                                        speexDecoder.processData(null, 0, bodybytes);
                                        for (int i = 1; i < nframes; i++)
                                        {
                                            speexDecoder.processData(true);
                                        }
                                    }
                                    else
                                    {
                                        speexDecoder.processData(payload, 0, bodybytes);
                                        for (int i = 1; i < nframes; i++)
                                        {
                                            speexDecoder.processData(false);
                                        }
                                    }
                                    if ((decsize = speexDecoder.getProcessedData(decdat, 0)) > 0)
                                    {
                                        writer.writePacket(decdat, 0, decsize);
                                    }
                                    packetNo++;
                                }
                            }
                        }
                        if (chksum != origchksum)
                        {
                            throw new System.IO.IOException("Ogg CheckSums do not match");
                        }
                    }
                    else
                    {
                        // Wave or Raw Speex
                        if (packetNo == 0)
                        {
                            if (srcFormat == FILE_FORMAT_WAVE)
                            {
                                // read the WAVE header
                                dis.readFully(header, 0, WAV_HEADERSIZE + 4);
                                // make sure its a WAVE header
                                if (!RIFF.Equals(cspeex.StringUtil.getStringForBytes(header, 0, 4)) && !WAVE.Equals
                                    (cspeex.StringUtil.getStringForBytes(header, 8, 4)))
                                {
                                    System.Console.Error.WriteLine("Not a WAVE file");
                                    return;
                                }
                                // Read other header chunks
                                dis.readFully(header, 0, WAV_HEADERSIZE);
                                string chunk = cspeex.StringUtil.getStringForBytes(header, 0, 4);
                                int size = readInt(header, 4);
                                while (!chunk.Equals(DATA))
                                {
                                    dis.readFully(header, 0, size);
                                    if (chunk.Equals(FORMAT))
                                    {
                                        if (readShort(header, 0) != WAVE_FORMAT_SPEEX)
                                        {
                                            System.Console.Error.WriteLine("Not a Wave Speex file");
                                            return;
                                        }
                                        channels = readShort(header, 2);
                                        sampleRate = readInt(header, 4);
                                        bodybytes = readShort(header, 12);
                                        if (readShort(header, 16) < 82)
                                        {
                                            System.Console.Error.WriteLine("Possibly corrupt Speex Wave file.");
                                            return;
                                        }
                                        readSpeexHeader(header, 20, 80);
                                        // Display audio info
                                        if (printlevel <= DEBUG)
                                        {
                                            System.Console.WriteLine("File Format: Wave Speex");
                                            System.Console.WriteLine("Sample Rate: " + sampleRate);
                                            System.Console.WriteLine("Channels: " + channels);
                                            System.Console.WriteLine("Encoder mode: " + (mode == 0 ? "Narrowband" : (mode
                                                 == 1 ? "Wideband" : "UltraWideband")));
                                            System.Console.WriteLine("Frames per packet: " + nframes);
                                        }
                                    }
                                    dis.readFully(header, 0, WAV_HEADERSIZE);
                                    chunk = cspeex.StringUtil.getStringForBytes(header, 0, 4);
                                    size = readInt(header, 4);
                                }
                                if (printlevel <= DEBUG)
                                {
                                    System.Console.WriteLine("Data size: " + size);
                                }
                            }
                            else
                            {
                                if (printlevel <= DEBUG)
                                {
                                    System.Console.WriteLine("File Format: Raw Speex");
                                    System.Console.WriteLine("Sample Rate: " + sampleRate);
                                    System.Console.WriteLine("Channels: " + channels);
                                    System.Console.WriteLine("Encoder mode: " + (mode == 0 ? "Narrowband" : (mode
                                         == 1 ? "Wideband" : "UltraWideband")));
                                    System.Console.WriteLine("Frames per packet: " + nframes);
                                }
                                speexDecoder.init(mode, sampleRate, channels, enhanced);
                                if (!vbr)
                                {
                                    switch (mode)
                                    {
                                        case 0:
                                            {
                                                bodybytes = org.xiph.speex.NbEncoder.NB_FRAME_SIZE[org.xiph.speex.NbEncoder.NB_QUALITY_MAP
                                                    [quality]];
                                                break;
                                            }

                                        case 1:
                                            {
                                                //Wideband
                                                bodybytes = org.xiph.speex.SbEncoder.NB_FRAME_SIZE[org.xiph.speex.SbEncoder.NB_QUALITY_MAP
                                                    [quality]];
                                                bodybytes += org.xiph.speex.SbEncoder.SB_FRAME_SIZE[org.xiph.speex.SbEncoder.WB_QUALITY_MAP
                                                    [quality]];
                                                break;
                                            }

                                        case 2:
                                            {
                                                bodybytes = org.xiph.speex.SbEncoder.NB_FRAME_SIZE[org.xiph.speex.SbEncoder.NB_QUALITY_MAP
                                                    [quality]];
                                                bodybytes += org.xiph.speex.SbEncoder.SB_FRAME_SIZE[org.xiph.speex.SbEncoder.WB_QUALITY_MAP
                                                    [quality]];
                                                bodybytes += org.xiph.speex.SbEncoder.SB_FRAME_SIZE[org.xiph.speex.SbEncoder.UWB_QUALITY_MAP
                                                    [quality]];
                                                break;
                                            }

                                        default:
                                            {
                                                //*/
                                                throw new System.IO.IOException("Illegal mode encoundered.");
                                                break;
                                            }
                                    }
                                    bodybytes = (bodybytes + 7) >> 3;
                                }
                                else
                                {
                                    // We have read the stream to find out more
                                    bodybytes = 0;
                                }
                            }
                            if (destFormat == FILE_FORMAT_WAVE)
                            {
                                writer = new org.xiph.speex.PcmWaveWriter(sampleRate, channels);
                                if (printlevel <= DEBUG)
                                {
                                    System.Console.WriteLine(string.Empty);
                                    System.Console.WriteLine("Output File: " + destPath);
                                    System.Console.WriteLine("File Format: PCM Wave");
                                    System.Console.WriteLine("Perceptual Enhancement: " + enhanced);
                                }
                            }
                            else
                            {
                                writer = new org.xiph.speex.RawWriter();
                                if (printlevel <= DEBUG)
                                {
                                    System.Console.WriteLine(string.Empty);
                                    System.Console.WriteLine("Output File: " + destPath);
                                    System.Console.WriteLine("File Format: Raw Audio");
                                    System.Console.WriteLine("Perceptual Enhancement: " + enhanced);
                                }
                            }
                            writer.open(destPath);
                            writer.writeHeader(null);
                            packetNo++;
                        }
                        else
                        {
                            dis.readFully(payload, 0, bodybytes);
                            if (loss > 0 && random.nextInt(100) < loss)
                            {
                                speexDecoder.processData(null, 0, bodybytes);
                                for (int i = 1; i < nframes; i++)
                                {
                                    speexDecoder.processData(true);
                                }
                            }
                            else
                            {
                                speexDecoder.processData(payload, 0, bodybytes);
                                for (int i = 1; i < nframes; i++)
                                {
                                    speexDecoder.processData(false);
                                }
                            }
                            if ((decsize = speexDecoder.getProcessedData(decdat, 0)) > 0)
                            {
                                writer.writePacket(decdat, 0, decsize);
                            }
                            packetNo++;
                        }
                    }
                }
            }
            catch (java.io.EOFException)
            {
            }
            writer.close();
        }
Exemplo n.º 2
0
        // ---|
        public virtual void encode(java.io.File srcPath, java.io.File destPath)
        {
            byte[] temp = new byte[2560];
            // stereo UWB requires one to read 2560b
            int HEADERSIZE = 8;
            string RIFF = "RIFF";
            string WAVE = "WAVE";
            string FORMAT = "fmt ";
            string DATA = "data";
            int WAVE_FORMAT_PCM = unchecked((int)(0x0001));
            // Display info
            if (printlevel <= INFO)
            {
                version();
            }
            if (printlevel <= DEBUG)
            {
                System.Console.WriteLine(string.Empty);
            }
            if (printlevel <= DEBUG)
            {
                System.Console.WriteLine("Input File: " + srcPath);
            }
            // Open the input stream
            java.io.DataInputStream dis = new java.io.DataInputStream(new java.io.FileInputStream
                (srcPath));
            // Prepare input stream
            if (srcFormat == FILE_FORMAT_WAVE)
            {
                // read the WAVE header
                dis.readFully(temp, 0, HEADERSIZE + 4);
                // make sure its a WAVE header
                if (!RIFF.Equals(cspeex.StringUtil.getStringForBytes(temp, 0, 4)) && !WAVE.Equals(cspeex.StringUtil.getStringForBytes
                    (temp, 8, 4)))
                {
                    System.Console.Error.WriteLine("Not a WAVE file");
                    return;
                }
                // Read other header chunks
                dis.readFully(temp, 0, HEADERSIZE);
                string chunk = cspeex.StringUtil.getStringForBytes(temp, 0, 4);
                int size = readInt(temp, 4);
                while (!chunk.Equals(DATA))
                {
                    dis.readFully(temp, 0, size);
                    if (chunk.Equals(FORMAT))
                    {
                        if (readShort(temp, 0) != WAVE_FORMAT_PCM)
                        {
                            System.Console.Error.WriteLine("Not a PCM file");
                            return;
                        }
                        channels = readShort(temp, 2);
                        sampleRate = readInt(temp, 4);
                        if (readShort(temp, 14) != 16)
                        {
                            System.Console.Error.WriteLine("Not a 16 bit file " + readShort(temp, 18));
                            return;
                        }
                        // Display audio info
                        if (printlevel <= DEBUG)
                        {
                            System.Console.WriteLine("File Format: PCM wave");
                            System.Console.WriteLine("Sample Rate: " + sampleRate);
                            System.Console.WriteLine("Channels: " + channels);
                        }
                    }
                    dis.readFully(temp, 0, HEADERSIZE);
                    chunk = cspeex.StringUtil.getStringForBytes(temp, 0, 4);
                    size = readInt(temp, 4);
                }
                if (printlevel <= DEBUG)
                {
                    System.Console.WriteLine("Data size: " + size);
                }
            }
            else
            {
                if (sampleRate < 0)
                {
                    switch (mode)
                    {
                        case 0:
                            {
                                sampleRate = 8000;
                                break;
                            }

                        case 1:
                            {
                                sampleRate = 16000;
                                break;
                            }

                        case 2:
                            {
                                sampleRate = 32000;
                                break;
                            }

                        default:
                            {
                                sampleRate = 8000;
                                break;
                            }
                    }
                }
                // Display audio info
                if (printlevel <= DEBUG)
                {
                    System.Console.WriteLine("File format: Raw audio");
                    System.Console.WriteLine("Sample rate: " + sampleRate);
                    System.Console.WriteLine("Channels: " + channels);
                    System.Console.WriteLine("Data size: " + srcPath.length());
                }
            }
            // Set the mode if it has not yet been determined
            if (mode < 0)
            {
                if (sampleRate < 100)
                {
                    // Sample Rate has probably been given in kHz
                    sampleRate *= 1000;
                }
                if (sampleRate < 12000)
                {
                    mode = 0;
                }
                else
                {
                    // Narrowband
                    if (sampleRate < 24000)
                    {
                        mode = 1;
                    }
                    else
                    {
                        // Wideband
                        mode = 2;
                    }
                }
            }
            // Ultra-wideband
            // Construct a new encoder
            org.xiph.speex.SpeexEncoder speexEncoder = new org.xiph.speex.SpeexEncoder();
            speexEncoder.init(mode, quality, sampleRate, channels);
            if (complexity > 0)
            {
                speexEncoder.getEncoder().setComplexity(complexity);
            }
            if (bitrate > 0)
            {
                speexEncoder.getEncoder().setBitRate(bitrate);
            }
            if (vbr)
            {
                speexEncoder.getEncoder().setVbr(vbr);
                if (vbr_quality > 0)
                {
                    speexEncoder.getEncoder().setVbrQuality(vbr_quality);
                }
            }
            if (vad)
            {
                speexEncoder.getEncoder().setVad(vad);
            }
            if (dtx)
            {
                speexEncoder.getEncoder().setDtx(dtx);
            }
            // Display info
            if (printlevel <= DEBUG)
            {
                System.Console.WriteLine(string.Empty);
                System.Console.WriteLine("Output File: " + destPath);
                System.Console.WriteLine("File format: Ogg Speex");
                System.Console.WriteLine("Encoder mode: " + (mode == 0 ? "Narrowband" : (mode== 1 ? "Wideband" : "UltraWideband")));
                System.Console.WriteLine("Quality: " + (vbr ? vbr_quality : quality));
                System.Console.WriteLine("Complexity: " + complexity);
                System.Console.WriteLine("Frames per packet: " + nframes);
                System.Console.WriteLine("Varible bitrate: " + vbr);
                System.Console.WriteLine("Voice activity detection: " + vad);
                System.Console.WriteLine("Discontinouous Transmission: " + dtx);
            }
            // Open the file writer
            org.xiph.speex.AudioFileWriter writer;
            if (destFormat == FILE_FORMAT_OGG)
            {
                writer = new org.xiph.speex.OggSpeexWriter(mode, sampleRate, channels, nframes, vbr
                    );
            }
            else
            {
                if (destFormat == FILE_FORMAT_WAVE)
                {
                    nframes = org.xiph.speex.PcmWaveWriter.WAVE_FRAME_SIZES[mode - 1][channels - 1][quality
                        ];
                    writer = new org.xiph.speex.PcmWaveWriter(mode, quality, sampleRate, channels, nframes
                        , vbr);
                }
                else
                {
                    writer = new org.xiph.speex.RawWriter();
                }
            }
            writer.open(destPath);
            writer.writeHeader("Encoded with: " + VERSION);
            int pcmPacketSize = 2 * channels * speexEncoder.getFrameSize();
            try
            {
                // read until we get to EOF
                while (true)
                {
                    dis.readFully(temp, 0, nframes * pcmPacketSize);
                    for (int i = 0; i < nframes; i++)
                    {
                        speexEncoder.processData(temp, i * pcmPacketSize, pcmPacketSize);
                    }
                    int encsize = speexEncoder.getProcessedData(temp, 0);
                    if (encsize > 0)
                    {
                        writer.writePacket(temp, 0, encsize);
                    }
                }
            }
            catch (java.io.EOFException)
            {
            }
            writer.close();
            dis.close();
        }