Grabadora de Sonido

Iniciado por rigorvzla, 21 Diciembre 2017, 13:39 PM

0 Miembros y 1 Visitante están viendo este tema.

rigorvzla

Cambiando de tema, navegando por internet encontre un codigo interesante que te permite capturar todo el sonido que sale de las cornetas, esta basado en linea de comandos

namespace GrabadoraCMD
{
    class Program
    {
        [DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);

        static void Main(string[] args)
        {
            mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
            mciSendString("record recsound", "", 0, 0);
            Console.WriteLine("recording, press Enter to stop and save ...");
            Console.ReadLine();

            mciSendString("save recsound c:\\work\\result.wav", "", 0, 0);
            mciSendString("close recsound ", "", 0, 0);
        }
    }
}


solo que al correrlo, abre pero no graba y no guarda nada , me podrian decir que falta ?

encontre otra mas elaborada creada por un arabe que segun graba lo que entra en el microfono y tambien la salida de las cornetas, pero leyendo en los comentarios habia gente que decia lo mismo que yo, faltaban cosas.

Import System.Runtime.InteropServices namespace

    using System.Diagnostics; 
     using System; 
     using System.Windows.Forms; 
     using System.Collections; 
     using System.Drawing; 
     using Microsoft.VisualBasic; 
     using System.Data; 
     using System.Collections.Generic; 
     using System.Runtime.InteropServices; 

Now, in your code module, create a function named record that will access the winmm.dll

    [DllImport("winmm.dll",EntryPoint="mciSendStringA", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)] 
    private static extern int record(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback); 

For record button for Button1, put this code below

    public void Button1_Click(System.Object sender, System.EventArgs e) 
    { 
       timer1.Enabled = true; 
       timer1.Start(); 
       record("open new Type waveaudio Alias recsound", "", 0, 0);   
       record("record recsound", "", 0, 0);   
    } 

The function named record was called here to open a wav audio file that is named as recsound. Then this will record sound as you click the record button. Note: Provide headset with microphone or speaker in your PC or laptop for you to say the words to record.

For save and stop button for Button2, put this code below

    public void Button2_Click(System.Object sender, System.EventArgs e) 
    { 
       timer1.Stop(); 
       timer1.Enabled = false; 
       record("save recsound d:\\mic.wav", "", 0, 0); 
       record("close recsound", "", 0, 0); 
    } 

The recsound alias that we initialized in the record button was called here. This button will save the recorded audio file and saved into D directory and will named as mic.wav. Then after saving, we close the recorded sound.

For play button for Button3, put this code below

    public void Button3_Click(System.Object sender, System.EventArgs e) 
    { 
       ms = 0; 
       h = 0; 
       s = 0; 
       m = 0; 
       timer1.Enabled = false; 
       lblhur.Text = "00"; 
       lblmin.Text = "00"; 
       lblsecond.Text = "00"; 
       (new Microsoft.VisualBasic.Devices.Audio()).Play("d:\\mic.wav"); 
    } 

We used the Play function in Audio to play the saved file in D Directory, the mic.wav, that we recorded its sound earlier.Click first record, say the words you wanted to say, click the save button, and play it.


ahi esta la explicacion la cual segui al pie de la letra pero todo quedo mal.

Eleкtro

#1
Cita de: rigorvzla en 21 Diciembre 2017, 13:39 PMme podrian decir que falta ?

En mi caso el código me funciona, pero claro el directorio de salida debe existir...
Código (csharp) [Seleccionar]
System.IO.Directory.CreateDirectory(@"C:\work");

Si ya te diste cuenta de eso y ya probaste en un directorio que si existe pero la grabación de audio sigue sin funcionarte, entonces depura el valor de retorno de la función mciSendString (todas las veces que la llamas), es la forma más efectiva para descubrir y comprender por que motivo no funciona en tu PC...

Cita de: MSDNReturn value

Returns zero if successful or an error otherwise. The low-order word of the returned DWORD value contains the error return value. If the error is device-specific, the high-order word of the return value is the driver identifier; otherwise, the high-order word is zero. For a list of possible error values, see MCIERR Return Values.

To retrieve a text description of return values, pass the return value to the mciGetErrorString function.

En este enlace tienes los nombres de los errores y sus descripciones:

Y aquí tienes los valores, los he sacado de la SDK de Windows 8.1 (lo más aconsejable sería que te descargues la SDK de tu misma versión de Windows ya que podría haber valores añadidos).


/* mmsyscom.h */
#define MCIERR_BASE            256

/* mciapi.h */
/* MCI error return values */
#define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
#define MCIERR_UNRECOGNIZED_KEYWORD     (MCIERR_BASE + 3)
#define MCIERR_UNRECOGNIZED_COMMAND     (MCIERR_BASE + 5)
#define MCIERR_HARDWARE                 (MCIERR_BASE + 6)
#define MCIERR_INVALID_DEVICE_NAME      (MCIERR_BASE + 7)
#define MCIERR_OUT_OF_MEMORY            (MCIERR_BASE + 8)
#define MCIERR_DEVICE_OPEN              (MCIERR_BASE + 9)
#define MCIERR_CANNOT_LOAD_DRIVER       (MCIERR_BASE + 10)
#define MCIERR_MISSING_COMMAND_STRING   (MCIERR_BASE + 11)
#define MCIERR_PARAM_OVERFLOW           (MCIERR_BASE + 12)
#define MCIERR_MISSING_STRING_ARGUMENT  (MCIERR_BASE + 13)
#define MCIERR_BAD_INTEGER              (MCIERR_BASE + 14)
#define MCIERR_PARSER_INTERNAL          (MCIERR_BASE + 15)
#define MCIERR_DRIVER_INTERNAL          (MCIERR_BASE + 16)
#define MCIERR_MISSING_PARAMETER        (MCIERR_BASE + 17)
#define MCIERR_UNSUPPORTED_FUNCTION     (MCIERR_BASE + 18)
#define MCIERR_FILE_NOT_FOUND           (MCIERR_BASE + 19)
#define MCIERR_DEVICE_NOT_READY         (MCIERR_BASE + 20)
#define MCIERR_INTERNAL                 (MCIERR_BASE + 21)
#define MCIERR_DRIVER                   (MCIERR_BASE + 22)
#define MCIERR_CANNOT_USE_ALL           (MCIERR_BASE + 23)
#define MCIERR_MULTIPLE                 (MCIERR_BASE + 24)
#define MCIERR_EXTENSION_NOT_FOUND      (MCIERR_BASE + 25)
#define MCIERR_OUTOFRANGE               (MCIERR_BASE + 26)
#define MCIERR_FLAGS_NOT_COMPATIBLE     (MCIERR_BASE + 28)
#define MCIERR_FILE_NOT_SAVED           (MCIERR_BASE + 30)
#define MCIERR_DEVICE_TYPE_REQUIRED     (MCIERR_BASE + 31)
#define MCIERR_DEVICE_LOCKED            (MCIERR_BASE + 32)
#define MCIERR_DUPLICATE_ALIAS          (MCIERR_BASE + 33)
#define MCIERR_BAD_CONSTANT             (MCIERR_BASE + 34)
#define MCIERR_MUST_USE_SHAREABLE       (MCIERR_BASE + 35)
#define MCIERR_MISSING_DEVICE_NAME      (MCIERR_BASE + 36)
#define MCIERR_BAD_TIME_FORMAT          (MCIERR_BASE + 37)
#define MCIERR_NO_CLOSING_QUOTE         (MCIERR_BASE + 38)
#define MCIERR_DUPLICATE_FLAGS          (MCIERR_BASE + 39)
#define MCIERR_INVALID_FILE             (MCIERR_BASE + 40)
#define MCIERR_NULL_PARAMETER_BLOCK     (MCIERR_BASE + 41)
#define MCIERR_UNNAMED_RESOURCE         (MCIERR_BASE + 42)
#define MCIERR_NEW_REQUIRES_ALIAS       (MCIERR_BASE + 43)
#define MCIERR_NOTIFY_ON_AUTO_OPEN      (MCIERR_BASE + 44)
#define MCIERR_NO_ELEMENT_ALLOWED       (MCIERR_BASE + 45)
#define MCIERR_NONAPPLICABLE_FUNCTION   (MCIERR_BASE + 46)
#define MCIERR_ILLEGAL_FOR_AUTO_OPEN    (MCIERR_BASE + 47)
#define MCIERR_FILENAME_REQUIRED        (MCIERR_BASE + 48)
#define MCIERR_EXTRA_CHARACTERS         (MCIERR_BASE + 49)
#define MCIERR_DEVICE_NOT_INSTALLED     (MCIERR_BASE + 50)
#define MCIERR_GET_CD                   (MCIERR_BASE + 51)
#define MCIERR_SET_CD                   (MCIERR_BASE + 52)
#define MCIERR_SET_DRIVE                (MCIERR_BASE + 53)
#define MCIERR_DEVICE_LENGTH            (MCIERR_BASE + 54)
#define MCIERR_DEVICE_ORD_LENGTH        (MCIERR_BASE + 55)
#define MCIERR_NO_INTEGER               (MCIERR_BASE + 56)

#define MCIERR_WAVE_OUTPUTSINUSE        (MCIERR_BASE + 64)
#define MCIERR_WAVE_SETOUTPUTINUSE      (MCIERR_BASE + 65)
#define MCIERR_WAVE_INPUTSINUSE         (MCIERR_BASE + 66)
#define MCIERR_WAVE_SETINPUTINUSE       (MCIERR_BASE + 67)
#define MCIERR_WAVE_OUTPUTUNSPECIFIED   (MCIERR_BASE + 68)
#define MCIERR_WAVE_INPUTUNSPECIFIED    (MCIERR_BASE + 69)
#define MCIERR_WAVE_OUTPUTSUNSUITABLE   (MCIERR_BASE + 70)
#define MCIERR_WAVE_SETOUTPUTUNSUITABLE (MCIERR_BASE + 71)
#define MCIERR_WAVE_INPUTSUNSUITABLE    (MCIERR_BASE + 72)
#define MCIERR_WAVE_SETINPUTUNSUITABLE  (MCIERR_BASE + 73)

#define MCIERR_SEQ_DIV_INCOMPATIBLE     (MCIERR_BASE + 80)
#define MCIERR_SEQ_PORT_INUSE           (MCIERR_BASE + 81)
#define MCIERR_SEQ_PORT_NONEXISTENT     (MCIERR_BASE + 82)
#define MCIERR_SEQ_PORT_MAPNODEVICE     (MCIERR_BASE + 83)
#define MCIERR_SEQ_PORT_MISCERROR       (MCIERR_BASE + 84)
#define MCIERR_SEQ_TIMER                (MCIERR_BASE + 85)
#define MCIERR_SEQ_PORTUNSPECIFIED      (MCIERR_BASE + 86)
#define MCIERR_SEQ_NOMIDIPRESENT        (MCIERR_BASE + 87)

#define MCIERR_NO_WINDOW                (MCIERR_BASE + 90)
#define MCIERR_CREATEWINDOW             (MCIERR_BASE + 91)
#define MCIERR_FILE_READ                (MCIERR_BASE + 92)
#define MCIERR_FILE_WRITE               (MCIERR_BASE + 93)

#define MCIERR_NO_IDENTITY              (MCIERR_BASE + 94)

/* all custom device driver errors must be >= than this value */
#define MCIERR_CUSTOM_DRIVER_BASE       (MCIERR_BASE + 256)


Saludos.








rigorvzla

#2
en efecto, solo faltaba la ruta de para crear la carpeta y el lo guardara, lo probe y si graba lo que sale de las cornetas (con una calidad baja cabe mencionar), pero cumple el cometido, ahora te pregunto hay alguna manera de adaptarla a wpf?

por que eh probado con otras cosas y no eh tenido exito, ya en algunos casos eh podido cambiar de form a wpf, pero nuca de CMD a wpf, ya que esto solo quiero agregar 2 botones rec y stop/save(automatico) alguna idea ?


EDITO: Resulta que probando la grabadora NO graba lo que sale de las cornetas , solo captura el microfono, tomaba las cornetas por que es sensible y a lo capturaba el sonido de las cornetas por el microfono, vuelvo al inicio. en este caso como puedo hacer que en vez de el microfono me capture las cornetas este ejemplo que consegui en internet?  using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; 

namespace GrabadoraCMD
{
    class Program
    {
        [DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);

        static void Main(string[] args)
        {
            mciSendString("open new Type waveaudio Alias recsound", "", 0, 0);
            mciSendString("record recsound", "", 0, 0);
            Console.WriteLine("Grabando, Presioe ENTER para detener...");
            Console.ReadLine();

            System.IO.Directory.CreateDirectory(@"C:\Grabaciones");
            mciSendString("save recsound c:\\Grabaciones\\result.wav", "", 0, 0);
            mciSendString("close recsound ", "", 0, 0);
           
        }
    }
}

Eleкtro

#3
Cita de: rigorvzla en 21 Diciembre 2017, 15:27 PMlo probe y si graba lo que sale de las cornetas (con una calidad baja cabe mencionar)

En la función MciSendString puedes establecer la calidad para grabar un archivo.wav a 44.1000 khz y 192.000 kbps. Es que no lees... copias y pegas códigos sin documentarte de las funciones de la API de Windows que estás usando en el código copiado, y así obtienes resultados mediocres hechos por gente con conocimientos medicores (no me refiero a ti, sino al árabe ese, y al otro del que le copiaste el código), en este caso obtienes un código que efectua una grabación con calidad muy mediocre (y no sabes por qué, ni tampoco si eso tiene solución, por que no has leido nada al respecto).

Estoy cansado de decirlo, pero no me rendiré, en la MSDN tienes todo lo que necesitas saber sobre la programación de .NET Framework y de Windows en general....


...Ahí tienes todos los parámetros disponibles para el tipo waveaudio del comando "set" de MCI... para establecer la calidad de audio.

La sintaxis para realizar una grabación WAVE estéreo y de calidad decente, sería así:
Código (csharp) [Seleccionar]
string alias = "nombre_de_alias";

string openCommand =
   string.Format("open new type waveaudio alias {0} wait", alias);

string setCommand =
   string.Format("set {0} time format ms bitspersample {1} channels {2} samplespersec {3} bytespersec {4} alignment {5}",
                 alias, 16, 2, 44100, 192000, 4);

string recordCommand =
   string.Format("record {0}", alias);

NativeMethods.MciSendString(openCommand, null, 0, IntPtr.Zero);
NativeMethods.MciSendString(setCommand, null, 0, IntPtr.Zero);
NativeMethods.MciSendString(recordCommand, null, 0, IntPtr.Zero);





Cita de: rigorvzla en 21 Diciembre 2017, 15:27 PMahora te pregunto hay alguna manera de adaptarla a wpf?

No entiendo la pregunta, ¿adaptar exactamente el que?. Que yo sepa los ensamblados de WPF no exponen ningún miembro administrado para la grabación de audio (quizás me equivoco, es un conjunto de namespaces muy extenso, pero he buscado y no hay nada), así que si no quieres depender de librerías de terceros (ej. nAudio) (algo que en mi opinión sería mucho mejor opción que utilizar MCI), la API de MCI es tu única opción.




Citarrec y stop/save(automatico) alguna idea ?

Para grabar, arriba te mostré como.

Para detener la grabación solo tienes que enviar el comando "stop" de MCI, junto al alias que le hayas asignado a la grabación...
Código (csharp) [Seleccionar]
NativeMethods.MciSendString(string.Format("stop {0}", alias), null, 0, IntPtr.Zero);

Y por último usarías el comando "save" de MCI para guardar la grabación en un archivo local:
Código (csharp) [Seleccionar]
NativeMethods.MciSendString(string.Format(@"save {0} ""{1}""", alias, @"C:\Ruta existente\audio.wav"), null, 0, IntPtr.Zero);





EDITO:

Por cierto, te sugiero que utilices la misma definciión que uso yo en mi librería ElektroKit:

Código (vbnet) [Seleccionar]
<SuppressUnmanagedCodeSecurity>
<DllImport("WinMM.dll", EntryPoint:="mciSendString", SetLastError:=True, CharSet:=CharSet.Auto, BestFitMapping:=False, ThrowOnUnmappableChar:=True)>
Public Shared Function MciSendString(ByVal command As String,
                                     ByVal buffer As StringBuilder,
                                     ByVal bufferSize As Integer,
                                     ByVal hWndCallback As IntPtr
) As Integer
End Function


Saludos.








Eleкtro

#4
Cita de: rigorvzla en 21 Diciembre 2017, 15:27 PM
EDITO: Resulta que probando la grabadora NO graba lo que sale de las cornetas , solo captura el microfono, tomaba las cornetas por que es sensible y a lo capturaba el sonido de las cornetas por el microfono, vuelvo al inicio. en este caso como puedo hacer que en vez de el microfono me capture las cornetas este ejemplo que consegui en internet?

Se graba lo que suena en el dispositivo de grabación predeterminado, así que en tu sistema operativo debes establecer el dispositivo de salida de grabación correcto, que en mi caso sería este (para que te hagas una idea):



Si quieres obtener más control para poder seleccionar el dispositivo de grabación en tiempo de ejecución, y grabar lo que suena en ese dispositivo, entonces te recomiendo usar la librería de terceros que ya te mencioné, nAudio:

Con esa librería es bastante sencillo enumerar los dispositivos o mixers instalados en el equipo, e iniciar una grabación en varios formatos de audio. Aquí tienes un ejemplo aleatorio:

Saludos.








rigorvzla

si supieras, pisaba por ese lado de sonido predeterminado, solo que nunca imagine en cambiar el microfono por el mezclador, lo coloque en predeterminado y me grabo el sonido , feo pero lo grabo, y si estoy con el nAudio pero es que no allo como empezar por que lo veo complicado, incluso con ese ejemplo que me das ya lo tengo en favoritos pero al copiarlo me da errores no se que falta como tal.

si funcionara ya abria empezado a observar de donde sale cada cosa y demas.

Gracias por esto ya se que si sirve jeje ya vere como aprender nAudio