예제 #1
0
        private int RunCycleAndFind(WavInfo wav, Func <double, bool> condition, bool isLeftToRight, int startPos = -1, bool breakAtValue = true)
        {
            if (isLeftToRight)
            {
                if (startPos == -1)
                {
                    startPos = 0;
                }

                for (int i = startPos; i < wav.Amplitudes.Length; ++i)
                {
                    if (condition(wav.Amplitudes[i]) == breakAtValue)
                    {
                        return(i);
                    }
                }
            }
            else
            {
                if (startPos == -1)
                {
                    startPos = wav.Amplitudes.Length - 1;
                }

                for (int i = startPos; i >= 0; --i)
                {
                    if (condition(wav.Amplitudes[i]) == breakAtValue)
                    {
                        return(i);
                    }
                }
            }

            return(-1);
        }
예제 #2
0
        private static void ReadDataSection(BinaryReader reader, WavInfo info, int subChunk2Size, int numChannels)
        {
            int           samples = subChunk2Size / info.BlockAlign;
            List <double> bytes   = new List <double>(samples);

            for (int i = 0, channel = 0; i < samples; channel = (channel == numChannels - 1) ? 0 : channel + 1)
            {
                Int16 ampl = 0;
                switch (info.BitsPerSample)
                {
                case 8:
                    ampl = (Int16)reader.ReadByte();
                    break;

                case 16:
                {
                    ampl = reader.ReadInt16();
                }
                break;

                default:
                    Trace.Fail("Bits per second: expected 8 or 16");
                    break;
                }

                if (channel == 0)
                {
                    bytes.Add(ampl / (float)(short.MaxValue));
                    ++i;
                }
            }

            info.Amplitudes = bytes.ToArray();
        }
예제 #3
0
        public static WavEditor Modify(WavInfo wavInfo)
        {
            var editor = new WavEditor();

            editor.wav = CloneWav(wavInfo);

            return(editor);
        }
예제 #4
0
        public static WavInfo Load(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    WavInfo info = new WavInfo();

                    var chunkId = reader.ReadInt32();
                    Trace.Assert(chunkId == 0x46464952);

                    var chunkSize = reader.ReadInt32();

                    var format = reader.ReadInt32();
                    Trace.Assert(format == 0x45564157);

                    var subChunk1Id = reader.ReadInt32();
                    Trace.Assert(subChunk1Id == 0x20746d66);

                    var subChunk1Size = reader.ReadInt32();

                    var audioFormat = reader.ReadInt16();
                    Trace.Assert(audioFormat == 1);

                    var numChannels = reader.ReadInt16();

                    info.SampleRate    = reader.ReadInt32();
                    info.ByteRate      = reader.ReadInt32();
                    info.BlockAlign    = reader.ReadInt16();
                    info.BitsPerSample = reader.ReadInt16();

                    if (subChunk1Size == 18)
                    {
                        // Read any extra values
                        int fmtExtraSize = reader.ReadInt16();
                        reader.ReadBytes(fmtExtraSize);
                    }

                    var subChunk2Id = reader.ReadInt32();
                    Trace.Assert(subChunk2Id == 0x61746164);

                    var subChunk2Size = reader.ReadInt32();

                    ReadDataSection(reader, info, subChunk2Size, numChannels);

                    info.BlockAlign = (short)(info.BitsPerSample / 8);
                    info.ByteRate  /= numChannels;

                    return(info);
                }
            }
        }
예제 #5
0
        public static WavEditor CreateWav(WavInfo settings)
        {
            var editor = new WavEditor();

            editor.wav               = new WavInfo();
            editor.wav.Amplitudes    = new double[0];
            editor.wav.BitsPerSample = settings.BitsPerSample;
            editor.wav.BlockAlign    = settings.BlockAlign;
            editor.wav.ByteRate      = settings.ByteRate;
            editor.wav.SampleRate    = settings.SampleRate;

            return(editor);
        }
예제 #6
0
        private static WavInfo CloneWav(WavInfo wavInfo, bool copyAmplitude = true)
        {
            var o = new WavInfo();

            o.SampleRate    = wavInfo.SampleRate;
            o.ByteRate      = wavInfo.ByteRate;
            o.BlockAlign    = wavInfo.BlockAlign;
            o.BitsPerSample = wavInfo.BitsPerSample;

            if (copyAmplitude)
            {
                o.Amplitudes = (double[])wavInfo.Amplitudes.Clone();
            }
            else
            {
                o.Amplitudes = null;
            }

            return(o);
        }
예제 #7
0
        public static void Save(string fileName, WavInfo info)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    writer.Write((Int32)0x46464952);                                                                           //"RIFF"
                    writer.Write((Int32)(4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 4 + 4 + info.Amplitudes.Length * sizeof(Int16))); //Length of file - 8
                    writer.Write((Int32)0x45564157);                                                                           //"WAVE"
                    writer.Write((Int32)0x20746d66);                                                                           //"fmt"
                    writer.Write((Int32)16);                                                                                   //Length of the fmt block
                    writer.Write((Int16)1);                                                                                    //PCM format
                    writer.Write((Int16)1);                                                                                    //Number of channels
                    writer.Write((Int32)info.SampleRate);
                    writer.Write((Int32)info.ByteRate);
                    writer.Write((Int16)info.BlockAlign);
                    writer.Write((Int16)info.BitsPerSample);
                    writer.Write((Int32)0x61746164);//"data"
                    writer.Write((Int32)(info.Amplitudes.Length * sizeof(Int16)));

                    writer.Write(info.Amplitudes.Select(v => (short)(v * short.MaxValue)).SelectMany(a => BitConverter.GetBytes(a)).ToArray());
                }
            }
        }
예제 #8
0
 public WavEditor MixWith(WavInfo other, double timeOffset = 0, double k1 = 1, double k2 = 1)
 {
     return(MixWith(other, (int)(timeOffset * wav.SampleRate), k1, k2));
 }
예제 #9
0
        public WavEditor MixWith(WavInfo other, int offset = 0, double k1 = 1, double k2 = 1)
        {
            var thisWav = wav;

            wav = CloneWav(wav, false);

            int newLength = thisWav.Amplitudes.Length + other.Amplitudes.Length;

            int intersectionFrom = Math.Max(0, offset);
            int intersectionTo   = Math.Min(thisWav.Amplitudes.Length, other.Amplitudes.Length + offset);

            if (intersectionFrom < intersectionTo)
            {
                newLength -= intersectionTo - intersectionFrom;
            }
            else
            {
                newLength += intersectionFrom - intersectionTo;
            }

            wav.Amplitudes = new double[newLength];
            if (offset < 0)
            {
                foreach (var region in freezedRegions)
                {
                    region.From -= offset;
                    region.To   -= offset;
                }
            }

            for (int i = 0, d = Math.Max(-offset, 0); i < thisWav.Amplitudes.Length; ++i)
            {
                wav.Amplitudes[i + d] = thisWav.Amplitudes[i] * k1;
            }

            Add((double v, int i) =>
            {
                if (offset < 0)
                {
                    if (i >= other.Amplitudes.Length)
                    {
                        return(0);
                    }

                    return(other.Amplitudes[i] * k2);
                }
                else
                {
                    if ((i - offset) < 0)
                    {
                        return(0);
                    }
                    if ((i - offset) >= other.Amplitudes.Length)
                    {
                        return(0);
                    }

                    return(other.Amplitudes[i - offset] * k2);
                }
            });

            return(this);
        }