Ejemplo n.º 1
0
    public void Add(NodeHuf nodeHuf)
    {
        Count++;
        Node aux;

        if (Head == null || Head.element.Frequency > nodeHuf.Frequency)
        {
            Head = new Node(nodeHuf, Head);
        }
        else
        {
            aux = Head;
            while (aux.nodeNext != null && aux.nodeNext.element.Frequency <= nodeHuf.Frequency)
            {
                aux = aux.nodeNext;
            }
            aux.nodeNext = new Node(nodeHuf, aux.nodeNext);
            //aux = new Node(nodeHuf, aux.nodeNext);
        }

        if (Count == 1)
        {
            Tail = Head;
        }
        else
        {
            aux = Head;
            while (aux.nodeNext != null)
            {
                aux = aux.nodeNext;
            }
            Tail = aux;
        }
    }
Ejemplo n.º 2
0
    //algoritmo de huffman
    public void Build()
    {
        while (Count > 1)
        {
            NodeHuf newNH = new NodeHuf();
            newNH.Symbol    = -666;
            newNH.Left      = Head.element;
            Head            = Head.nodeNext;
            newNH.Right     = Head.element;
            Head            = Head.nodeNext;
            newNH.Frequency = newNH.Left.Frequency + newNH.Right.Frequency;
            Count          -= 2;
            Add(newNH);
        }
        //Indicamos la raíz del árbol de huffman.
        Root = Head.element;

        //La cabeza y cola de la lista enlazada ya no serán utilizadas.
        Head = Tail = null;
    }
Ejemplo n.º 3
0
    public short[] Decode(BitArray bits)
    {
        NodeHuf current = this.Root;

        short[] decoded = new short[bits.Length];
        int     i       = 0;

        foreach (bool bit in bits)
        {
            if (bit)
            {
                if (current.Right != null)
                {
                    current = current.Right;
                }
            }
            else
            {
                if (current.Left != null)
                {
                    current = current.Left;
                }
            }

            //Con este método sabremos cuando se ha llegado a un símbolo u hoja.
            if (IsLeaf(current))
            {
                //decoded += current.Symbol;
                decoded[i] = current.Symbol;
                i++;
                current = this.Root;
            }
        }

        return(decoded);
    }
Ejemplo n.º 4
0
 public Node(NodeHuf element, Node next = null)
 {
     this.element = element;
     nodeNext     = next;
 }
Ejemplo n.º 5
0
 public bool IsLeaf(NodeHuf node)
 {
     return(node.Left == null && node.Right == null);
 }
Ejemplo n.º 6
0
        void backWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            System.ComponentModel.BackgroundWorker b = sender as System.ComponentModel.BackgroundWorker;
            int samples = 32;

            short[] buffer = new short[samples];
            bw = new BinaryWriter(File.Open(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/Code.huf", FileMode.Create));

            stream = Bass.BASS_StreamCreateFile(path, 0L, 0L, BASSFlag.BASS_STREAM_DECODE);

            ww = new WaveWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/HufSound.wav", stream, true);
            int  mult = 0;
            long len  = Bass.BASS_ChannelGetLength(stream, BASSMode.BASS_POS_BYTES);

            while (Bass.BASS_ChannelIsActive(stream) == BASSActive.BASS_ACTIVE_PLAYING)
            {
                int length = Bass.BASS_ChannelGetData(stream, buffer, samples * 2);
                mult++;
                b.ReportProgress((int)(((samples * mult) * 100) / len * 2));
                List <short> listBuffer = new List <short>();
                HuffmanTree  tree       = new HuffmanTree();
                if (length > 0)
                {
                    listBuffer.AddRange(buffer);
                    short[] auxbuf = new short[buffer.Length];
                    auxbuf = buffer;
                    canvasWavComp.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.SystemIdle, new Action(delegate
                    {
                        //Whole Wave
                        //double xScale = canvasWavComp.Width / samples;

                        //Formula by Manuel García. Dude you're amazing.
                        //NOTE: multiply by 2 'cos I supoused some relation with Nyquist Theorem
                        double xScale = (canvasWavComp.Width * samples) / len * 2;

                        double yScale      = (canvasWavComp.Height / (double)(amplitude * 2)) * ((double)amplitude / MAX_AMP);
                        Polyline graphLine = new Polyline();

                        //This Line is used to move on the x axis
                        Canvas.SetLeft(graphLine, xAxis);

                        graphLine.Stroke          = new SolidColorBrush(Color.FromRgb(244, 67, 54));
                        graphLine.StrokeThickness = 2;
                        for (int i = 0; i < buffer.Length; i++)
                        {
                            graphLine.Points.Add(new Point(xScale * i, (canvasWavComp.Height / 2) - (buffer[i] * yScale)));
                        }
                        xAxis += xScale;
                        //canvasWavComp.Children.Clear();
                        canvasWavComp.Children.Add(graphLine);
                    }));
                    double entaux = 0;
                    foreach (var sym in listBuffer.GroupBy(i => i))
                    {
                        NodeHuf nodeHuf = new NodeHuf();
                        nodeHuf.Symbol    = sym.Key;
                        nodeHuf.Frequency = sym.Count();
                        nodeHuf.Right     = nodeHuf.Left = null;
                        tree.Add(nodeHuf);
                        double prob = (double)nodeHuf.Frequency / samples;
                        //entropy -= prob * (Math.Log(prob) / Math.Log(2));
                        entaux   += prob * Math.Log(1 / (prob), 2);
                        entauxlbl = entaux;
                    }
                    entropy += entaux;
                    entcount++;
                    tree.Build();


                    //Encode
                    System.Collections.BitArray encoded = tree.Encode(auxbuf);
                    byte[] arrayBytes = new byte[encoded.Length / 8 + (encoded.Length % 8 == 0 ? 0 : 1)];
                    encoded.CopyTo(arrayBytes, 0);
                    File.WriteAllBytes("Compress.bin", arrayBytes);

                    //Decode
                    byte[] data;
                    Stream fs = File.OpenRead("Compress.bin");
                    data = new byte[fs.Length];
                    fs.Read(data, 0, data.Length);
                    System.Collections.BitArray bitDec = new System.Collections.BitArray(data);

                    short[] decoded = tree.Decode(bitDec);
                    if (decoded.Length > 0)
                    {
                        ww.Write(decoded, length);
                    }
                    bw.Write(data);
                    fs.Close();
                }
            }
            //Delete temporaly file
            File.Delete("Compress.bin");

            //Close de Stream WAV ww
            ww.Close();

            //If you not add this line, the backgroundworker will be restat but when file is create again
            //there will be an incongruence because the bw never was closed.
            bw.Close();

            entropy /= entcount;// (len / samples);
            entcount = 0;
        }