Запись Wav в файл - C#

Узнай цену своей работы

Формулировка задачи:

Пишу на C#. Имеется написанный код для записи звука с микрофона в поток(исходник будет ниже). Мне надо сохранить его в файл формата Wav чтоб воспроизводилось в плеере (но если честно файл wav будет нужен для других целей)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using Microsoft.DirectX.DirectSound;
using Buffer = Microsoft.DirectX.DirectSound.Buffer;
 
namespace vs3
{
    class Record
    {
        public static WaveFormat _waveFormat;
        //свойство формат
        public static WaveFormat waveFormat
        {
            get
            {
                return _waveFormat;
            }
        }
        private static UInt16 sizeBufer = 22050;
        private static MemoryStream stream;
        private static MemoryStream tempStream;
        //свойство размер
        public static int Length
        {
            get
            {
                return (int)stream.Length;
            }
        }
        public static byte[] Data
        {
            get
            {
                switch (regim)
                {
                    case 0: break;
                    case 1: RecordStop(); break;
                    case 2: PlayStop(); break;
                }
                return stream.ToArray();
            }
        }
        public static byte regim = 0;
 
        private static Capture capture;
        private static CaptureBufferDescription captureBuffDesc;
        private static CaptureBuffer recordBuff;
 
        private static AutoResetEvent autoResetEventRec;
        private static BufferPositionNotify[] positionNotifyRec;
        private static Notify notifyRec;
 
        private static Thread threadRec;
 
        private static Device device;
        private static Buffer playBuff;
        private static BufferDescription secondBuffDesc;
 
        private static System.Windows.Forms.Control control = null;
        private static Thread threadPlay;
 
        private static AutoResetEvent autoResetEventPlay;
        private static BufferPositionNotify[] positionNotifyPlay;
        private static Notify notifyPlay;
        public static void Create(System.Windows.Forms.Control _control)
        {
            control = _control;
            SetWaveFormat();
            SetTempStream();
            SetPlayBuff();
            SetRecordBuff();
            SetNotifyPlay();
            SetNotifyRecord();
        }
        private static void SetTempStream()
        {
            ushort i, n = (ushort)(sizeBufer);
            byte[] temp = new byte[n];
            if (_waveFormat.BitsPerSample == 8)
            {
                for (i = 0; i < n; i++) temp[i] = 127;
                tempStream = new MemoryStream(temp);
                return;
            }
            if (_waveFormat.BitsPerSample == 16)
            {
                for (i = 0; i < n; i++) temp[i] = 0;
                tempStream = new MemoryStream(temp);
                return;
            }
        }
        private static void SetWaveFormat()
        {
            _waveFormat = new WaveFormat();
            _waveFormat.BitsPerSample = 8;
            _waveFormat.BlockAlign = 1;
            _waveFormat.Channels = 1;
            _waveFormat.AverageBytesPerSecond = 22050;
            _waveFormat.SamplesPerSecond = 22050;
            _waveFormat.FormatTag = WaveFormatTag.Pcm;
        }
        private static void SetRecordBuff()
        {
            capture = new Capture();
            captureBuffDesc = new CaptureBufferDescription();
            captureBuffDesc.BufferBytes = sizeBufer;
            captureBuffDesc.Format = _waveFormat;
            recordBuff = new CaptureBuffer(captureBuffDesc, capture);
        }
        private static void SetNotifyRecord()
        {
            autoResetEventRec = new AutoResetEvent(false);
            positionNotifyRec = new BufferPositionNotify[2];
            positionNotifyRec[0].Offset = sizeBufer / 2 - 1;
            positionNotifyRec[0].EventNotifyHandle = autoResetEventRec.SafeWaitHandle.DangerousGetHandle();
            positionNotifyRec[1].Offset = sizeBufer - 1;
            positionNotifyRec[1].EventNotifyHandle = autoResetEventRec.SafeWaitHandle.DangerousGetHandle();
            notifyRec = new Notify(recordBuff);
            notifyRec.SetNotificationPositions(positionNotifyRec, 2);
        }
        private static void Recording()
        {
            int offset = 0;
            int a, b;
            recordBuff.GetCurrentPosition(out a, out b);
            if (a == 0) { offset = sizeBufer / 2; b = sizeBufer / 2; }
            else if (a < sizeBufer / 2) { offset = sizeBufer / 2; b = sizeBufer / 2 - a; }
            else { offset = 0; b = sizeBufer - a; }

            recordBuff.Start(true);
            autoResetEventRec.WaitOne(Timeout.Infinite, true);
            recordBuff.Read(a, stream, b, LockFlag.None);
            for (; ; )
            {
                autoResetEventRec.WaitOne(Timeout.Infinite, true);
                recordBuff.Read(offset, stream, sizeBufer / 2, LockFlag.None);
                offset = (offset + sizeBufer / 2) % (sizeBufer);
            }
        }
        private static void RecordStart()
        {
            switch (regim)
            {
                case 0: break;
                case 1: RecordStop(); break;
                case 2: PlayStop(); break;
            }
            regim = 1;
            stream = new MemoryStream();
            threadRec = new Thread(new ThreadStart(Recording));
            threadRec.Start();
        }
        private static void RecordStop()
        {
            if (regim != 1) return;
            int a, b;
 
            threadRec.Abort();
            recordBuff.Stop();
            recordBuff.GetCurrentPosition(out a, out b);
 
            if (a == sizeBufer / 2 || a == sizeBufer) { regim = 0; return; }
 
            if (a < sizeBufer / 2)
            {
                recordBuff.Read(0, stream, a, LockFlag.None);
            }
            else
            {
                recordBuff.Read(sizeBufer / 2, stream, a - sizeBufer / 2, LockFlag.None);
            }
            regim = 0;
        }
        private static void SetPlayBuff()
        {
            device = new Device();
            device.SetCooperativeLevel(control, CooperativeLevel.Priority);
            secondBuffDesc = new BufferDescription();
            secondBuffDesc.Format = _waveFormat;
            secondBuffDesc.BufferBytes = sizeBufer;
            secondBuffDesc.LocateInSoftware = true;
            secondBuffDesc.ControlPositionNotify = true;
            secondBuffDesc.ControlFrequency = true;
            secondBuffDesc.ControlPan = true;
            secondBuffDesc.ControlVolume = true;
            playBuff = new Buffer(secondBuffDesc, device);
 
        }
        private static void SetNotifyPlay()
        {
            autoResetEventPlay = new AutoResetEvent(false);
            positionNotifyPlay = new BufferPositionNotify[2];
            positionNotifyPlay[0].Offset = sizeBufer / 2 - 1;
            positionNotifyPlay[0].EventNotifyHandle = autoResetEventPlay.SafeWaitHandle.DangerousGetHandle();
            positionNotifyPlay[1].Offset = sizeBufer - 1;
            positionNotifyPlay[1].EventNotifyHandle = autoResetEventPlay.SafeWaitHandle.DangerousGetHandle();
            notifyPlay = new Notify(playBuff);
            notifyPlay.SetNotificationPositions(positionNotifyPlay, 2);
        }
        private static void Playing()
        {
 
            uint i, num = (uint)(stream.Length / (sizeBufer / 2));
            int offset, ostatok = (int)stream.Length % (sizeBufer / 2);
 
            if (num < 2)
            {
                playBuff.Write(0, stream, (int)stream.Length, LockFlag.None);
                playBuff.Write((int)stream.Length, tempStream, sizeBufer - (int)stream.Length, LockFlag.None);
                playBuff.Play(0, BufferPlayFlags.Default);
                return;
            }
 
            playBuff.Write(0, stream, sizeBufer, LockFlag.None);
            playBuff.Play(0, BufferPlayFlags.Looping);
            autoResetEventPlay.WaitOne(Timeout.Infinite, true);
            for (offset = 0, i = 2; i <= num; i++)
            {
                if (i != num)
                {
                    playBuff.Write(offset, stream, sizeBufer / 2, LockFlag.None);
                }
                else
                {
                    playBuff.Write(offset, stream, ostatok, LockFlag.None);
                    playBuff.Write(offset + ostatok, tempStream, sizeBufer / 2 - ostatok, LockFlag.None);
                }
                offset = (offset + sizeBufer / 2) % sizeBufer;
                autoResetEventPlay.WaitOne(Timeout.Infinite, true);
            }
            autoResetEventPlay.WaitOne(Timeout.Infinite, true);
            playBuff.Stop();
            regim = 0;
        }
        private static void PlayStart()
        {
            switch (regim)
            {
                case 0: break;
                case 1: RecordStop(); break;
                case 2: PlayStop(); break;
            }
            regim = 2;
            stream.Position = 0;
            playBuff.SetCurrentPosition(0);
            tempStream.Position = 0;
            threadPlay = new Thread(new ThreadStart(Playing));
            threadPlay.Start();
        }
        private static void PlayStop()
        {
            if (regim == 2)
            {
                threadPlay.Abort();
                playBuff.Stop();
                regim = 0;
            }
        }
        public static void Record1()
        {
            RecordStart();
        }
 
        public static void Play()
        {
            PlayStart();
 
        }
        public static int Stop()
        {
            switch (regim)
            {
                case 1: RecordStop(); return 1;
                case 2: PlayStop(); return 2;
                default: return 0;
            }
        }
        public static int Save(string Name)
        {
            //Вот надо сюда вставить.написать что-то чтобы сохранить 
            return 0;
        }
 
    }
}
Сам сломал голову!!! Если не сложно помогите)

Решение задачи: «Запись Wav в файл»

textual
Листинг программы
using System;
using System.IO;
using System.Runtime.InteropServices;
 
namespace WavFormatCSharp
{
    [StructLayout(LayoutKind.Sequential)]
    // Структура, описывающая заголовок WAV файла.
    internal class WavHeader
    {
        // WAV-формат начинается с RIFF-заголовка:
 
        // Содержит символы "RIFF" в ASCII кодировке
        // (0x52494646 в big-endian представлении)
        public UInt32 ChunkId;
 
        // 36 + subchunk2Size, или более точно:
        // 4 + (8 + subchunk1Size) + (8 + subchunk2Size)
        // Это оставшийся размер цепочки, начиная с этой позиции.
        // Иначе говоря, это размер файла - 8, то есть,
        // исключены поля chunkId и chunkSize.
        public UInt32 ChunkSize;
 
        // Содержит символы "WAVE"
        // (0x57415645 в big-endian представлении)
        public UInt32 Format;
    
        // Формат "WAVE" состоит из двух подцепочек: "fmt " и "data":
        // Подцепочка "fmt " описывает формат звуковых данных:
    
        // Содержит символы "fmt "
        // (0x666d7420 в big-endian представлении)
        public UInt32 Subchunk1Id;
        
        // 16 для формата PCM.
        // Это оставшийся размер подцепочки, начиная с этой позиции.
        public UInt32 Subchunk1Size;
 
        // Аудио формат, полный список можно получить здесь [url]http://audiocoding.ru/wav_formats.txt[/url]
        // Для PCM = 1 (то есть, Линейное квантование).
        // Значения, отличающиеся от 1, обозначают некоторый формат сжатия.
        public UInt16 AudioFormat;
    
        // Количество каналов. Моно = 1, Стерео = 2 и т.д.
        public UInt16 NumChannels;
 
        // Частота дискретизации. 8000 Гц, 44100 Гц и т.д.
        public UInt32 SampleRate;
 
        // sampleRate * numChannels * bitsPerSample/8
        public UInt32 ByteRate;
 
        // numChannels * bitsPerSample/8
        // Количество байт для одного сэмпла, включая все каналы.
        public UInt16 BlockAlign;
 
        // Так называемая "глубиная" или точность звучания. 8 бит, 16 бит и т.д.
        public UInt16 BitsPerSample;
 
        // Подцепочка "data" содержит аудио-данные и их размер.
 
        // Содержит символы "data"
        // (0x64617461 в big-endian представлении)
        public UInt32 Subchunk2Id;
 
        // numSamples * numChannels * bitsPerSample/8
        // Количество байт в области данных.
        public UInt32 Subchunk2Size;
 
        // Далее следуют непосредственно Wav данные.
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var header = new WavHeader();
            // Размер заголовка
            var headerSize = Marshal.SizeOf(header);
 
            var fileStream = new FileStream("Slipknot - Three Nil.wav", FileMode.Open, FileAccess.Read);
            var buffer = new byte[headerSize];
            fileStream.Read(buffer, 0, headerSize);
            
            // Чтобы не считывать каждое значение заголовка по отдельности,
            // воспользуемся выделением unmanaged блока памяти
            var headerPtr = Marshal.AllocHGlobal(headerSize);
            // Копируем считанные байты из файла в выделенный блок памяти
            Marshal.Copy(buffer, 0, headerPtr, headerSize);
            // Преобразовываем указатель на блок памяти к нашей структуре
            Marshal.PtrToStructure(headerPtr, header);
 
            // Выводим полученные данные
            Console.WriteLine("Sample rate: {0}", header.SampleRate);
            Console.WriteLine("Channels: {0}", header.NumChannels);
            Console.WriteLine("Bits per sample: {0}", header.BitsPerSample);
 
            // Посчитаем длительность воспроизведения в секундах
            var durationSeconds = 1.0 * header.Subchunk2Size / (header.BitsPerSample / 8.0) / header.NumChannels / header.SampleRate;
            var durationMinutes = (int)Math.Floor(durationSeconds / 60);
            durationSeconds = durationSeconds - (durationMinutes * 60);
            Console.WriteLine("Duration: {0:00}:{1:00}", durationMinutes, durationSeconds);
 
            Console.ReadKey();
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.571 из 5