Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it L'avatar di Keiji
    Registrato dal
    Mar 2008
    Messaggi
    15

    [C#] Registrare audio con directx

    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();
            }
        }
    
    }
    Keiji

  2. #2
    L'header del file è OK, ma la parte riservata a DATA non scrive un bel niente nel file. C'è qualche problerma.

    Anche io sto sviluppando un programma audio con al funzione registra...ma tra guide e controguide non riesco a capire molto.


    C'è un esempio sul web: http://www.notjustcode.it/dblog/arti...p?articolo=205

    Il programma non carica prima in memoria e poi salva, ma salva dei "pacchetti" sul file man mano che la registrazione va avanti.

    Il codice è funzionante (lo compilo con SharpDevelop) e scritto in VB.NET
    Io che provengo dal linguaggio C e programmo in C# non capisco molto Visual Basic e lo trovo spartano, non so tradurre. Nemmeno con il traduttore automatico.

    Quella guida poi non ti fa capire molto.

  3. #3
    guest.1
    Guest
    mi sa che hai sbagliato sezione, qui si parla di pagine web asp net.

    Devi farti spostare da un moderatore nella sezione programmazione.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.