Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2013, 12:37   #1
dar3dev1l26
Пользователь
 
Регистрация: 06.10.2011
Сообщений: 58
Стрелка C# работа с wav файлами

Мне нужно применить алгоритм непосредственно к области аудиоданных wav файла, а её надо сначала извлечь. Я этим заниматься вручную (писать класс для wav файлов) не очень хочу, своей работы с алгоритмом хватает, а поскольку я новичок это чревато ошибками; в общем время тратить не хочется. Погулил я немножко, но ничего путнего не нашел, в основном люди ищут как конвертировать, проигрывать и т д.
Существует ли в .NET Framework 3.5 класс (или какая-то бесплатная библиотека с таким классом в интернете), которая может мне помочь извлекать информацию из хэдера wav файла, считывать данные из блока данных?
Буду рад любым любым советам\комментариям.

Последний раз редактировалось dar3dev1l26; 12.04.2013 в 13:16.
dar3dev1l26 вне форума Ответить с цитированием
Старый 13.04.2013, 09:28   #2
dar3dev1l26
Пользователь
 
Регистрация: 06.10.2011
Сообщений: 58
Лампочка

Написал, если у кого-то такая же проблема и лень писать, можете использовать мой код.
Класс Wav файла:
Код:
public class WavFile
    {        
        public string path;
        //-----WaveHeader-----
        public char[] sGroupID; // RIFF
        public uint dwFileLength; // total file length minus 8, which is taken up by RIFF
        public char[] sRiffType;// always WAVE

        //-----WaveFormatChunk-----
        public char[] sFChunkID;         // Four bytes: "fmt "
        public uint dwFChunkSize;        // Length of header in bytes
        public ushort wFormatTag;       // 1 (MS PCM)
        public ushort wChannels;        // Number of channels
        public uint dwSamplesPerSec;    // Frequency of the audio in Hz... 44100
        public uint dwAvgBytesPerSec;   // for estimating RAM allocation
        public ushort wBlockAlign;      // sample frame size, in bytes
        public ushort wBitsPerSample;    // bits per sample

        //-----WaveDataChunk-----
        public char[] sDChunkID;     // "data"
        public uint dwDChunkSize;    // Length of header in bytes
        public byte dataStartPos;  // audio data start position
        
        public WavFile()
        {
            path = Environment.CurrentDirectory;
            //-----WaveHeader-----
            dwFileLength = 0;
            sGroupID = "RIFF".ToCharArray();
            sRiffType = "WAVE".ToCharArray();

            //-----WaveFormatChunk-----
            sFChunkID = "fmt ".ToCharArray();
            dwFChunkSize = 16;
            wFormatTag = 1;
            wChannels = 2;
            dwSamplesPerSec = 44100;
            wBitsPerSample = 16;
            wBlockAlign = (ushort)(wChannels * (wBitsPerSample / 8));
            dwAvgBytesPerSec = dwSamplesPerSec * wBlockAlign;

            //-----WaveDataChunk-----
            dataStartPos = 44;
            dwDChunkSize = 0;
            sDChunkID = "data".ToCharArray();
        }
    }
Мне не нужно никаким образом менять данные в хэдере или менять размер wav файла, мне нужно изменить с помощью своего алгоритма значения в блоке данных. Поэтому я действую так: создаю экземпляр класса WavFile инициализирую его поля с помощью BinaryReader, потом копирую файл с помощью BinaryWriter (когда дохожу до блока данных я их перед записью редактирую). Таким образом я имею копию исходного файла, только с звуковыми отредактированными данными.
Иницализация может быть такой:
Код:
wavFile.path = @"C:\Rammstein - Kokain.wav";
            FileStream fsr = new FileStream(wavFile.path, FileMode.Open, FileAccess.Read);
            BinaryReader r = new BinaryReader(fsr);            
            wavFile.sGroupID = r.ReadChars(4);   
            wavFile.dwFileLength = r.ReadUInt32(); 
            wavFile.sRiffType = r.ReadChars(4);    
            wavFile.sFChunkID = r.ReadChars(4);
            wavFile.dwFChunkSize = r.ReadUInt32();
            wavFile.wFormatTag = r.ReadUInt16();
            wavFile.wChannels = r.ReadUInt16();
            wavFile.dwSamplesPerSec = r.ReadUInt32();
            wavFile.dwAvgBytesPerSec = r.ReadUInt32();
            wavFile.wBlockAlign = r.ReadUInt16();
            wavFile.wBitsPerSample = r.ReadUInt16();
            wavFile.sDChunkID = r.ReadChars(4);
            wavFile.dwDChunkSize = r.ReadUInt32();            
            wavFile.dataStartPos = (byte)r.BaseStream.Position;
            r.Close();
            fsr.Close();
dar3dev1l26 вне форума Ответить с цитированием
Старый 13.04.2013, 09:29   #3
dar3dev1l26
Пользователь
 
Регистрация: 06.10.2011
Сообщений: 58
По умолчанию

Функция записи(здесь фактически копирование, надо обработать данные внутри цикла):
Код:
static void WriteWav()
        {
            FileStream fsr = new FileStream(wavFile.path, FileMode.Open, FileAccess.Read);
            BinaryReader r = new BinaryReader(fsr);
            string path = wavFile.path;
            path = path.Insert(path.Length - 4, "(+)");
            FileStream fsw = null;
            try
            {
                fsw = new FileStream(path, FileMode.CreateNew);
            }
            catch(IOException)
            {
                fsw = new FileStream(path, FileMode.Truncate);
            }
            BinaryWriter w = new BinaryWriter(fsw);
            int pos = 0, len = (int)r.BaseStream.Length; short temp;
            while (pos < len)
            {
                temp = (short)r.ReadInt16();
                //Working with the temp
                w.Write(temp);
                pos += 2;
            }
            r.Close();   w.Close();
            fsr.Close(); fsw.Close();    
        }
wavFile должен быть виден для WriteWav(). Так же я здесь не учёл много деталей,этот код будет работать для wav файлов с wFormatTag равным 1, в общем если блок данных будет начинаться не с 44 позиции, то могут быть ошибочки. Там могут быть дополнительные поля, которые Вы можете случайно изменить, если не заметите их присутствие. Если хотите работать с множеством разных типов wav файлов, то Вам придется делать дополнительные проверки.
Пользовался http://blogs.msdn.com/b/dawate/archi...o-using-c.aspx

Последний раз редактировалось dar3dev1l26; 13.04.2013 в 12:39.
dar3dev1l26 вне форума Ответить с цитированием
Старый 07.04.2016, 10:56   #4
AleK135
 
Регистрация: 31.03.2016
Сообщений: 3
По умолчанию

Я, наверное, сильно опоздал, но если кто-то интересуется, то вот код


Код:
using System;
using System.Collections.Generic;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        struct WavHeader
        {
            public byte[] riffID;
            public uint size;
            public byte[] wavID;
            public byte[] fmtID;
            public uint fmtSize;
            public ushort format;
            public ushort channels;
            public uint sampleRate;
            public uint bytePerSec;
            public ushort blockSize;
            public ushort bit;
            public byte[] dataID;
            public uint dataSize;
        }
        static void Main(string[] args)
        {
            WavHeader Header = new WavHeader();
            List<Int16> lDataList = new List<Int16>();

            using (FileStream fs = new FileStream("file name", FileMode.Open, FileAccess.Read))
            using (BinaryReader br = new BinaryReader(fs))
            {
                try
                {
                    Header.riffID = br.ReadBytes(4);//1
                    Header.size = br.ReadUInt32();//2
                    Header.wavID = br.ReadBytes(4);//3
                    Header.fmtID = br.ReadBytes(4);//4
                    Header.fmtSize = br.ReadUInt32();//5
                    Header.format = br.ReadUInt16();//6
                    Header.channels = br.ReadUInt16();//7
                    Header.sampleRate = br.ReadUInt32();//8
                    Header.bytePerSec = br.ReadUInt32();//9
                    Header.blockSize = br.ReadUInt16();//10
                    Header.bit = br.ReadUInt16();//11
                    Header.dataID = br.ReadBytes(6);//12
                    Header.dataSize = br.ReadUInt32();//13

                    int n = (int)(Header.dataSize/ Header.channels*8 / Header.bit);

                    for (int i = 0; i < n; i++)
                    {
                        Int16 tmp = 0;
                        tmp = br.ReadInt16();
                        lDataList.Add(tmp);
                    }
                }
                finally
                {
                    if (br != null)
                    {
                        br.Close();
                    }
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            }
            Console.WriteLine("Открыт");

            using (FileStream fs = new FileStream("file name", FileMode.Create, FileAccess.Write))
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                try
                {
                    bw.Write(Header.riffID);//1
                    bw.Write(Header.size);//2
                    bw.Write(Header.wavID);//3
                    bw.Write(Header.fmtID);//4
                    bw.Write(Header.fmtSize);//5
                    bw.Write(Header.format);//6
                    bw.Write(Header.channels);//7
                    bw.Write(Header.sampleRate);//8
                    bw.Write(Header.bytePerSec);//9
                    bw.Write(Header.blockSize);//10
                    bw.Write(Header.bit);//11
                    bw.Write(Header.dataID);//12
                    bw.Write(Header.dataSize);//13

                    int n = (int)(Header.dataSize / Header.channels * 8 / Header.bit);

                    for (int i = 0; i < n; i++)
                    {
                        Int16 tmp = lDataList[i];
                        bw.Write(tmp);
                    }
                    
                }
                finally
                {
                    if (bw != null)
                    {
                        bw.Close();
                    }
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            }

            return;
        }
    }
}

Последний раз редактировалось Alex11223; 07.04.2016 в 12:00.
AleK135 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
работа с wav-файлом vadim_gluzker C# (си шарп) 2 24.02.2011 00:36
работа с wav на низком уровне vsrmis Мультимедиа в Delphi 10 15.01.2011 01:13
играть сначала 1.wav потом 2.wav mma Мультимедиа в Delphi 9 23.12.2010 20:04
Работа с .wav dampirik Общие вопросы .NET 8 17.12.2010 00:07
Конвертация аудиофайлов WAV -> WAV namestnik Помощь студентам 2 27.05.2009 23:05