Ciao a tutti,
da un paio di giorni sto cercando di realizzare un registratore di suoni con player audio utilizzando la libreria "Microsoft.DirectX.DirectSound"
Per riprodurre file audio non ci sono stati problemi mentre per registrare sto riscontrando delle difficoltà!
Credo di non riuscire a impostare la proprietà CaptureBuffer.read perchè credo debba avviarsi automaticamente con la scrittura del buffer invece io qui la faccio partire al termine.
codice:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.DirectX.DirectSound; using Buffer = Microsoft.DirectX.DirectSound.Buffer; using System.IO; using System.Collections; namespace TestMyMediaPlayer { public partial class SoundRec : Form { private CaptureBuffer MySndBuf; private DeviceInformation deviceInfo; private Capture MyCapture; private CaptureDevicesCollection captureDeviceCollection; // Setto il formato di cattura senza effetti (22KHz 8bit/sample, mono) public SoundRec() { InitializeComponent(); MyCapture = new Capture(deviceInfo.DriverGuid); CaptureBufferDescription MySBufDesc = new CaptureBufferDescription(); captureDeviceCollection = new CaptureDevicesCollection(); //Controllo DEVICE di input if (captureDeviceCollection.Count == 0) throw new Exception("No Capture Devices"); //1 identifica realtek; 0 Driver primario di acquisizione suoni deviceInfo = captureDeviceCollection[1]; //formato cattura WaveFormat DefaultFormat = new WaveFormat(); DefaultFormat.SamplesPerSecond = 22000; //22khz (campioni al secondo) DefaultFormat.Channels = 1; //mono DefaultFormat.BitsPerSample = 8; DefaultFormat.AverageBytesPerSecond = 22000;//trasferimento medio di bytes al secondo DefaultFormat.BlockAlign = 1; //bytes di campionatura //formato buffer di cattura MySBufDesc.Format = DefaultFormat; MySBufDesc.BufferBytes = DefaultFormat.AverageBytesPerSecond/5;//dimensione buffer MySBufDesc.ControlEffects = false; //vieto la cattura degli effetti MySBufDesc.WaveMapped = true; //viene usato il waveMapped per i formati non supportati dalla device MySndBuf = new CaptureBuffer(MySBufDesc, MyCapture); } // Inizia la cattura public void StartRecord() { MySndBuf.Start(true);//alla fine del buffer ricomincia dall'inizio //(false) se non si stoppa alla fine del buffer crea eccezione // alla lettura dello stesso (MySndBuf.read) } // Ferma la cattura public void StopRecord() { MySndBuf.Stop(); } // Salvataggio dati da buffer a file wave public void ReadData() { int readposition; int writeposition; ArrayList byteArrayList = new ArrayList(); System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding(); //Creo il file o sovrascrivo se già esiste string nomefile = Application.StartupPath + "\\test.wav"; Stream MemStream = new MemoryStream(); MySndBuf.GetCurrentPosition(out writeposition, out readposition);//setta le posizioni di cattura e lettura MySndBuf.Read(0, MemStream, writeposition, LockFlag.None); Stream MyStream = new FileStream(nomefile, FileMode.Create); try { byteArrayList.AddRange(ascii.GetBytes("RIFF")); byteArrayList.AddRange(ToBytes(36 + (int)MemStream.Length, 4)); byteArrayList.AddRange(ascii.GetBytes("WAVE")); //fmt chunk byteArrayList.AddRange(ascii.GetBytes("fmt ")); //length of fmt chunk (never changes) byteArrayList.AddRange(ToBytes(16, 4)); //"1" for pcm encoding byteArrayList.AddRange(ToBytes(1, 2)); byteArrayList.AddRange(ToBytes(MySndBuf.Format.Channels, 2)); byteArrayList.AddRange(ToBytes(MySndBuf.Format.SamplesPerSecond, 4)); byteArrayList.AddRange(ToBytes(MySndBuf.Format.AverageBytesPerSecond, 4)); byteArrayList.AddRange(ToBytes(MySndBuf.Format.BlockAlign, 2)); byteArrayList.AddRange(ToBytes(MySndBuf.Format.BitsPerSample, 2)); //the data chunk byteArrayList.AddRange(ascii.GetBytes("data")); byteArrayList.AddRange(ToBytes((int)MemStream.Length, 4)); byte[] buffer = new byte[MemStream.Length]; MemStream.Read(buffer, 0, (int)MemStream.Length); byteArrayList.AddRange(buffer); buffer = new byte[byteArrayList.Count]; byteArrayList.CopyTo(buffer); MyStream.Write(buffer, 0, buffer.Length); } catch (ArgumentException ae) { MessageBox.Show("Argument Exception with Message:\n\t" + ae.Message); } finally { MemStream.Close(); MyStream.Close(); } } // controllo cattura public bool Capturing() { return MySndBuf.Capturing; } private ArrayList ToBytes(int targetnumber, short numofbytes) { int remainder, result; ArrayList returningarray; ArgumentException wrongnumofbytes = new ArgumentException("Not enough bytes to represent number", "numofbytes"); result = Math.DivRem(targetnumber, 256, out remainder); //if not enough bytes specified to represent target number if (targetnumber >= Math.Pow(256,(double)numofbytes)) { throw wrongnumofbytes; } //if there are higher significant hexadecima, run a recursion if (result >= 1) { returningarray = ToBytes(result, (short)(numofbytes-1)); returningarray.Insert(0, Convert.ToByte(remainder)); return returningarray; } else //if (result < 1) recursion terminating condition { returningarray = new ArrayList(numofbytes); returningarray.Add(Convert.ToByte(targetnumber)); for (int i=0; i < numofbytes-1; i++) { returningarray.Add(Convert.ToByte(0));//fill up most significant hexadecima with 0's } return returningarray; } } private void button1_Click(object sender, EventArgs e) { StartRecord(); if (Capturing()) this.label1.Text = "in cattura"; ReadData(); } private void button2_Click(object sender, EventArgs e) { StopRecord(); if (!Capturing()) this.label1.Text = "terminato"; //ReadData(); } } }

Rispondi quotando