Пример #1
0
        public CarenResult ObterDispositivosCaptura()
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Cria o enumerador de dispositivos.
            myCaptureAudio.EnumeradorDispositivos = new CarenMMDeviceEnumerator(CA_CLSCTX.CLSCTX_INPROC_SERVER);

            //Cria a interface que vai conter a coleção de dispositivos.
            myCaptureAudio.ColecaoDispositivos = new CarenMMDeviceCollection();

            //Chama o método para obter todos os dispositivos de captura.
            Resultado = myCaptureAudio.EnumeradorDispositivos.EnumAudioEndpoints(CA_EDataFlow.eCapture, CA_DEVICE_STATE_XXX.CA_DEVICE_STATE_ACTIVE, myCaptureAudio.ColecaoDispositivos);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao listar os dispositivos de captura disponiveis atualmente. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Obtém a quantidade de dispositivos disponiveis.
            Resultado = myCaptureAudio.ColecaoDispositivos.GetCount(out uint CountTotalDevices);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter a quantidade de disponiveis de captura obtidos. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define na propriedade na estrutura
            myCaptureAudio.CountDevicesCaptureCollection = CountTotalDevices;

            //Define sucesso na operação
            Resultado.AdicionarCodigo(ResultCode.SS_OK, true);

            Done :;

            //Retorna o resultado.
            return(Resultado);
        }
Пример #2
0
        /// <summary>
        /// Método responsável por criar e preparar o arquivo que vai receber os dados capturados do dispositivo de áudio.
        /// </summary>
        /// <param name="Param_Url">A url para o arquivo que será criado.</param>
        /// <returns></returns>
        public CarenResult CriarArquivoWav(String Param_Url)
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Variaveis
            ICarenBuffer BufferHeaderZero = null;
            ulong        RefTotalWritten  = 0;

            //Deleta o arquivo se ja existir.
            File.Delete(Param_Url);

            //Chama o construtor para criar o arquivo de destino.
            myCaptureAudio.StreamFile = new CarenStream(Param_Url, CA_STGMs.CA_STGM_READWRITE, CA_FILE_ATTRIBUTES.CA_FILE_ATTRIBUTE_NORMAL, true);

            //Verifica se não houve erro.
            if (myCaptureAudio.StreamFile is null)
            {
                //Define erro na operação.
                Resultado.AdicionarCodigo(ResultCode.ER_FAIL, false);

                //Sai do método.
                goto Done;
            }

            //Cria um buffer que vai conter o tamanho do HEADER do arquivo Wav, mais preenchidos com zero.
            BufferHeaderZero = new CarenBuffer();
            BufferHeaderZero.CreateBuffer(MyHeaderInfoFile.HeaderSize);

            //Preenche o buffer com Zeros.
            BufferHeaderZero.FillBuffer();

            //Escreve o tamanho do header no inicio do fluxo para poder reservar.
            Resultado = myCaptureAudio.StreamFile.Write(BufferHeaderZero, MyHeaderInfoFile.HeaderSize, ref RefTotalWritten);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao escrever o HEADER vazio no inicio do fluxo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define sucesso na operação
            Resultado.AdicionarCodigo(ResultCode.SS_OK, true);

            Done :;
            //Retorna
            return(Resultado);
        }
Пример #3
0
        /// <summary>
        /// Método responsável por criar a task que fica escrevendo os dados no buffer.
        /// </summary>
        public void IniciarEscritorDados()
        {
            //Cria o buffer que vai conter as amostras de áudio.
            ListaBuffersAudio = new List <ICarenBuffer>(SIZE_INITIAL_BUFFER);

            //Cria a task responsável por ficar escrever no arquivo.
            Task_EscritorDados = new Task(async() =>
            {
                //Variaveis
                CarenResult Resultado         = new CarenResult(ResultCode.ER_FAIL, false);
                ICarenBuffer BufferNextWriter = null;
                ulong RefTotalWrittenBytes    = 0;
                uint ActualSamplesWrited      = 0;

                //Define que o escritor de dados está processando
                StatusEscritorDados = true;

                //Define o status geral para true.
                StatusGeral = true;

                //Abre um laço que vai ficar escrevendo os dados no arquivo.
                while (StatusEscritorDados)
                {
                    //Verifica se o Status geral não é false.
                    if (!StatusGeral)
                    {
                        //Define que o laço vai sair
                        StatusEscritorDados = false;

                        //Sai do laço.
                        break;
                    }

                    //Verifica se tém buffers para serem escritos
                    if (GetCountBuffersAudio() <= 0)
                    {
                        goto Done; //Pula para o Delay.
                    }
                    //Remove e obtém o proximo buffer da lista a ser escrito.
                    BufferNextWriter = ObterProximaAmostra();

                    //Verifica se a amostra não é nula.
                    if (BufferNextWriter is null)
                    {
                        goto Done; //O buffer é invalido.
                    }
                    //Chama o método para escrever os dados no fluxo.
                    Resultado = myCaptureAudio.StreamFile.Write(BufferNextWriter, BufferNextWriter.TamanhoValido, ref RefTotalWrittenBytes);

                    //Verifica se não houve erro.
                    if (Resultado.StatusCode != ResultCode.SS_OK)
                    {
                        //A operação de escrita falhou.

                        //Mostra uma mensagem de erro.
                        ShowMensagem(
                            "Ocorreu uma falha ao escrever os dados do buffer de áudio no arquivo de destino. Mensagem de erro -> "
                            + Resultado.ObterMensagem((int)Resultado.HResult), true);

                        //Define que o status geral é false.
                        StatusGeral = false;

                        //Define que vai sair do laço.
                        StatusEscritorDados = false;
                    }

                    //Libera o buffer.
                    BufferNextWriter.ReleaseBuffer();
                    BufferNextWriter = null;

                    //Incrementa a quantidade de amostras escritas.
                    ActualSamplesWrited++;

                    //Verifica a quantidade e chama o GC se necessário.
                    if (ActualSamplesWrited >= 300)
                    {
                        //Chama o GC.
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        GC.Collect();

                        //Reseta a quantidade.
                        ActualSamplesWrited = 0;
                    }

                    //Chama o continue para pular o delay
                    continue;

                    Done:;
                    await Task.Delay(5);
                }

                //Chama o GC.
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            });

            //Inicia o escritor de dados.
            Task_EscritorDados.Start();
        }
Пример #4
0
        /// <summary>
        /// Método responsável por terminar de configurar o header e finalizar o arquivo.
        /// </summary>
        /// <returns></returns>
        public CarenResult FinalizarArquivoWav()
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Variaveis a serem utilizadas.
            ulong OutTotalWriter = 0;

            //Cria o buffer que vai conter os dados a serem escritos.
            ICarenBuffer BufferWriter = new CarenBuffer();

            //Cria o buffer para escrever os dados do header.
            BufferWriter.CreateBuffer(MyHeaderInfoFile.HeaderSize);

            //Calcula o tamanho total do arquivo.
            MyHeaderInfoFile.TotalFileSize = (uint)MyHeaderInfoFile.TotalLenghtCaptured + MyHeaderInfoFile.HeaderSize;

            //Escreve os dados do header.
            BufferWriter.Write(MFTFuncs._FCC("RIFF"));
            BufferWriter.Write(MyHeaderInfoFile.TotalFileSize);
            BufferWriter.Write(MFTFuncs._FCC("WAVE"));
            BufferWriter.Write(MFTFuncs._FCC("fmt "));
            BufferWriter.Write(MyHeaderInfoFile.SubChunkSize);
            BufferWriter.Write(MyHeaderInfoFile.FormatAudioData);                                                                 //Formato dos dados = IEEE Float.
            BufferWriter.Write(MyHeaderInfoFile.Canais);                                                                          //Quantidade de canais.
            BufferWriter.Write(MyHeaderInfoFile.SampleRate);                                                                      //Sample Rate.
            BufferWriter.Write((uint)MyHeaderInfoFile.BitsPerSample * MyHeaderInfoFile.Canais * MyHeaderInfoFile.SampleRate / 8); //Bytes per sample.
            BufferWriter.Write((ushort)(MyHeaderInfoFile.BitsPerSample * MyHeaderInfoFile.Canais / 8));                           //Alinhamento de bloco.
            BufferWriter.Write(MyHeaderInfoFile.BitsPerSample);                                                                   //Bitpersample
            BufferWriter.Write(MFTFuncs._FCC("data"));                                                                            //Marca inicio do buffer.
            BufferWriter.Write((uint)MyHeaderInfoFile.TotalLenghtCaptured);                                                       //Tamanho total dos dados de audio.

            //Define como posicação zero no fluxo.
            Resultado = myCaptureAudio.StreamFile.Seek(0, CA_STREAM_SEEK.CA_STREAM_SEEK_SET, out ulong NewSeekPos);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar definir uma posição no fluxo para escrita do header. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Chama o método para escrever os dados no fluxo.
            Resultado = myCaptureAudio.StreamFile.Write(BufferWriter, MyHeaderInfoFile.HeaderSize, ref OutTotalWriter);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar escrever os dados do header no fluxo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Consolida os dados do fluxo para o arquivo.
            Resultado = myCaptureAudio.StreamFile.Commit(CA_STGC.CA_STGC_CONSOLIDATE);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao consolidar os dados do header no fluxo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Libera o fluxo e sua referencia para o arquivo.
            myCaptureAudio.StreamFile.LiberarReferencia();
            myCaptureAudio.StreamFile.Finalizar();
            myCaptureAudio.StreamFile = null;

            Done :;

            //Retorna
            return(Resultado);
        }
Пример #5
0
        public CarenResult PararCapturaDados()
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Define para parar de capturar os dados.
            StatusCapturandoDados = false;

            //Aguarda um tempo até todos os dados tiverem sido escritos.
            while (Task_ReadDataDispositivo.Status == TaskStatus.Running)
            {
                WinFuncs.SleepNativo(100);
            }

            //Chama o método para parar o dispositivo de captura.
            Resultado = myCaptureAudio.AudioClientConfig.Stop();

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao pedir ao dispostivo de captura que parasse. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Aguarda o escritor de dados terminar de escrever todos os dados.
            while (ListaBuffersAudio.Count != 0)
            {
                WinFuncs.SleepNativo(100);
            }

            //Define para parar de escrveer dados.
            StatusGeral         = false;
            StatusEscritorDados = false;

            //Faz um delay
            WinFuncs.SleepNativo(500);

            //Chama o método para finalizar a criação do arquivo.
            Resultado = FinalizarArquivoWav();

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao terminar de definir os dados do header do arquivo final. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define sucesso na operação.
            Resultado.AdicionarCodigo(ResultCode.SS_OK, true);

            //Reverte todas as informações.
            WinFuncs._AvRevertMmThreadCharacteristics(myCaptureAudio.HandleTaskPrioridade);
            WinFuncs._TimeEndPeriod(5);

            Done :;

            //Retorna o resultado.
            return(Resultado);
        }
Пример #6
0
        public CarenResult IniciarCapturaDados()
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Define o volume de captura do volume.
            Resultado = myCaptureAudio.AudioCaptureVolume.SetMasterVolume(1.0f, GUID_SESSION_AUDIO);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar definir o volume de captura do dispositivo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Cria a task responsável pela captura dos dados do dispositivo.
            Task_ReadDataDispositivo = new Task(async() =>
            {
                //Define que está capturando dados.
                StatusCapturandoDados = true;

                //Variavies utilizadas.
                uint OutNextPacketSize = 0;
                uint SizeInBytesBuffer = 0;
                uint OutFramesReaded   = 0;
                CA_AUDIOCLIENTE_BUFFERFLAGS FlagsBuffer = CA_AUDIOCLIENTE_BUFFERFLAGS.Zero;
                ICarenBuffer BufferSilence = new CarenBuffer();

                //Define que essa thread deve ter uma latencia menor.
                WinFuncs._AvSetMmThreadCharacteristicsW(CA_Windows_MMCSS_Multimedia_Name_Tasks.Pro_Audio, out uint OutTaskIndex);

                //Define a TaskIndex na estrutura
                myCaptureAudio.TaskIndex = OutTaskIndex;

                //Abre o laço que vai ficar capturando os dados.
                while (StatusCapturandoDados)
                {
                    //Chama o método para recuperar a quantidade de frames do proximo pacote.
                    Resultado = myCaptureAudio.AudioCapture.GetNextPacketSize(out OutNextPacketSize);

                    //Verifica se obteve sucesso
                    if (Resultado.StatusCode != ResultCode.SS_OK)
                    {
                        //A operação falhou.

                        //Mostra uma mensagem de erro.
                        ShowMensagem(
                            "Ocorreu uma falha ao tentar obter o tamanho do proximo pacote de dados do dispositivo de captura. Mensagem de erro -> "
                            + Resultado.ObterMensagem((int)Resultado.HResult), true);

                        //Sai do laço
                        break;
                    }

                    //Abre um laço que vai ler todos os dados disponiveis do pacote atual e enviar para o escritor.
                    while (OutNextPacketSize != 0)
                    {
                        //Chama o método para ler os dados do dispositivo.
                        Resultado = myCaptureAudio.AudioCapture.GetBuffer(
                            out myCaptureAudio.BufferCapturedAudio,
                            out OutFramesReaded,
                            out FlagsBuffer,
                            out _,
                            out _);

                        //Verifica se obteve sucesso
                        if (Resultado.StatusCode != ResultCode.SS_OK)
                        {
                            //A operação falhou.

                            //Mostra uma mensagem de erro.
                            ShowMensagem(
                                "Ocorreu uma falha ao tentar caturar os dados disponiveis no dispositivo de captura. Mensagem de erro -> "
                                + Resultado.ObterMensagem((int)Resultado.HResult), true);

                            //Sai do laço
                            break;
                        }

                        //Define o tamanho do buffer lido do dispositivo.
                        SizeInBytesBuffer = OutFramesReaded * myCaptureAudio.FrameSize;

                        //Verifica os Flags do buffer.
                        if ((FlagsBuffer & CA_AUDIOCLIENTE_BUFFERFLAGS.AUDCLNT_BUFFERFLAGS_SILENT) != 0)
                        {
                            //Cria o buffer do tamanho dos dados capturados.
                            BufferSilence.CreateBuffer(SizeInBytesBuffer);

                            //Preenche o buffer com zeros.
                            BufferSilence.FillBuffer();

                            //Envia o buffer para o escritor de dados.
                            EnviarAmostra(ref BufferSilence, SizeInBytesBuffer);

                            //Libera a memória utilizada pelo buffer de silencio.
                            BufferSilence.ReleaseBuffer();
                        }
                        else
                        {
                            //Define as informações no buffer capturado.
                            myCaptureAudio.BufferCapturedAudio.TamanhoValido = SizeInBytesBuffer;
                            myCaptureAudio.BufferCapturedAudio.Tamanho       = SizeInBytesBuffer;
                            myCaptureAudio.BufferCapturedAudio.SetPosition(0);

                            //Envia o buffer para o escritor de dados.
                            EnviarAmostra(ref myCaptureAudio.BufferCapturedAudio, SizeInBytesBuffer);
                        }

                        //Chama o método para liberar o buffer.
                        Resultado = myCaptureAudio.AudioCapture.ReleaseBuffer(OutFramesReaded);

                        //Verifica se obteve sucesso
                        if (Resultado.StatusCode != ResultCode.SS_OK)
                        {
                            //A operação falhou.

                            //Mostra uma mensagem de erro.
                            ShowMensagem(
                                "Ocorreu uma falha ao tentar liberar o buffer capturado anteriormente. Mensagem de erro -> "
                                + Resultado.ObterMensagem((int)Resultado.HResult), true);

                            //Sai do laço
                            break;
                        }

                        //Incrementa a quantidade de dados capturados.
                        MyHeaderInfoFile.TotalLenghtCaptured += SizeInBytesBuffer;

                        //Chama o método para recuperar a quantidade de frames do proximo pacote.
                        Resultado = myCaptureAudio.AudioCapture.GetNextPacketSize(out OutNextPacketSize);

                        //Verifica se obteve sucesso
                        if (Resultado.StatusCode != ResultCode.SS_OK)
                        {
                            //A operação falhou.

                            //Mostra uma mensagem de erro.
                            ShowMensagem(
                                "Ocorreu uma falha ao tentar obter o tamanho do proximo pacote de dados do dispositivo de captura. Mensagem de erro -> "
                                + Resultado.ObterMensagem((int)Resultado.HResult), true);

                            //Sai do laço
                            break;
                        }
                    }

                    //Zera o tamanho do pacote.
                    OutNextPacketSize = 0;

                    //Faz um pequeno delay.
                    await Task.Delay(5);
                }
            });

            //Define um tempo menor para o delay do sistema.
            WinFuncs._TimeBeginPeriod(5);

            //Chama o método para iniciar o dispositivo de captura para obter os dados.
            Resultado = myCaptureAudio.AudioClientConfig.Start();

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao solicitar que o dispositivo de captura inicie a captura dos dados. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Inicia a task de captura.
            Task_ReadDataDispositivo.Start();

            Done :;

            //Retorna o resultado.
            return(Resultado);
        }
Пример #7
0
        public CarenResult AtivarDispositivoCapturaByIndex(uint Param_IdDevice)
        {
            //Variavel que vai retornar o resultado.
            CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false);

            //Tenta recuperar o dispositivo de captura indicado pelo id.
            Resultado = myCaptureAudio.ColecaoDispositivos.Item(Param_IdDevice, out ICarenMMDevice OutDeviceCapture);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter o dispositivo de captura indicado pelo Id. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define o dispositivo de captura no membro da estrutura.
            myCaptureAudio.DispositivoCaptura = OutDeviceCapture;

            //Cria a interface que vai ser ativada.
            myCaptureAudio.AudioClientConfig = new CarenAudioClient();

            //Tenta ativar o dispositivo.
            Resultado = OutDeviceCapture.Activate(GUIDs_InterfacesWASAPI.IID_IAudioClient, CA_CLSCTX.CLSCTX_INPROC_SERVER, null, myCaptureAudio.AudioClientConfig);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar ativar o dispositivo selecionado. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Obtém o formato que o dispostivo de captura suporta
            Resultado = myCaptureAudio.AudioClientConfig.GetMixFormat(out CA_WAVEFORMATEXEXTENSIBLE OutWaveFormatCapture);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter o tipo de dados suportado pelo dispositivo de captura. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define na estrutura.
            myCaptureAudio.WavFormatCapture = OutWaveFormatCapture;

            //Calcula os dados do formato do áudio e define nas estruturas.
            myCaptureAudio.FrameSize         = (uint)(OutWaveFormatCapture.Format.wBitsPerSample * OutWaveFormatCapture.Format.nChannels / 8);
            MyHeaderInfoFile.Canais          = OutWaveFormatCapture.Format.nChannels;
            MyHeaderInfoFile.BitsPerSample   = OutWaveFormatCapture.Format.wBitsPerSample;
            MyHeaderInfoFile.SampleRate      = OutWaveFormatCapture.Format.nSamplesPerSec;
            MyHeaderInfoFile.BytesPerSec     = OutWaveFormatCapture.Format.nSamplesPerSec * OutWaveFormatCapture.Format.wBitsPerSample * OutWaveFormatCapture.Format.nChannels / 8;
            MyHeaderInfoFile.BlockAlign      = OutWaveFormatCapture.Format.nBlockAlign;
            MyHeaderInfoFile.FormatAudioData = (ushort)(OutWaveFormatCapture.SubFormato == GUIDs_MF_AUDIO_SUBTYPES.MFAudioFormat_PCM ? 0x0 : 0x0003); //0x0003 é o formato IEEE Float

            //Inicializa o dispositivo de captura.
            Resultado = myCaptureAudio.AudioClientConfig.Initialize(
                CA_AUDIOCLIENTE_SHAREMODE.AUDCLNT_SHAREMODE_SHARED,
                0,
                REFTIMES_PER_SEC,
                0,
                ref OutWaveFormatCapture,
                GUID_SESSION_AUDIO);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar inicializar o dispositivo de captura. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Obtém o tamanho do buffer selecionado pelo dispositivo.
            Resultado = myCaptureAudio.AudioClientConfig.GetBufferSize(out uint OutBufferInFrames);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter o tamanho do buffer selecionado pelo dispositivo de captura. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define na estrutura,
            myCaptureAudio.BufferSizeInFames = OutBufferInFrames;

            //Inicializa a interface de captura que vai ser criada.
            myCaptureAudio.AudioCapture = new CarenAudioCaptureClient();

            //Chama o método para obter a interface de captura de áudio.
            Resultado = myCaptureAudio.AudioClientConfig.GetService(GUIDs_InterfacesWASAPI.IID_IAudioCaptureClient, myCaptureAudio.AudioCapture);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter a interface responsável pela captura dos dados de áudio do dispositivo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Inicializa a interface de controle de volume
            myCaptureAudio.AudioCaptureVolume = new CarenSimpleAudioVolume();

            //Obtém a interface que controla o volume do áudio.
            Resultado = myCaptureAudio.AudioClientConfig.GetService(GUIDs_InterfacesWASAPI.IID_ISimpleAudioVolume, myCaptureAudio.AudioCaptureVolume);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter a interface de controle de volume do áudio. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            Done :;

            //Retorna o resultado.
            return(Resultado);
        }
Пример #8
0
        public String ObterNomeDispositivoByIndex(uint Param_IdDevice)
        {
            //Variavel que vai retornar o resultado.
            String NomeDispositivo = string.Empty;

            //Variaveis utilizadas.
            CarenResult    Resultado = new CarenResult(ResultCode.ER_FAIL, false);
            CA_PROPERTYKEY PropKey   = new CA_PROPERTYKEY()
            {
                GUIDProp = GUIDs_CoreAudio_Propriedades.PKEY_Device_FriendlyName, PID = GUIDs_CoreAudio_Propriedades.PID_Device_FriendlyName
            };


            //Tenta recuperar o dispositivo de captura indicado pelo id.
            Resultado = myCaptureAudio.ColecaoDispositivos.Item(Param_IdDevice, out ICarenMMDevice OutDeviceCapture);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter o dispositivo de captura indicado pelo Id. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Chama o método para obter a loja de propriedades do dispositivo.
            Resultado = OutDeviceCapture.OpenPropertyStore(CA_STGMs.CA_STGM_READ, out ICarenPropertyStore OutPropStore);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Libera a referencia para o dispositivo de captura.
                OutDeviceCapture.LiberarReferencia();
                OutDeviceCapture.Finalizar();
                OutDeviceCapture = null;

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter a interface de propriedades do dispositivo. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Chama o método para obter o nome do dispositivo de captura.
            Resultado = OutPropStore.GetValue(ref PropKey, out CA_PROPVARIANT OutPropValor);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Libera a referencia para o dispositivo de captura.
                OutDeviceCapture.LiberarReferencia();
                OutPropStore.LiberarReferencia();
                OutDeviceCapture.Finalizar();
                OutPropStore.Finalizar();
                OutDeviceCapture = null;
                OutPropStore     = null;

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao obter o nome do dispositivo.. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Define o nome do dispositivo na variavel de retorno.
            NomeDispositivo = OutPropValor.pwszVal;

            //Libera as interfaces e dados.
            OutDeviceCapture.LiberarReferencia();
            OutPropStore.LiberarReferencia();
            OutDeviceCapture.Finalizar();
            OutPropStore.Finalizar();
            OutDeviceCapture = null;
            OutPropStore     = null;
            OutPropValor     = null;

            //Chama o GC.
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Done :;

            //Retorna o resultado.
            return(NomeDispositivo);
        }
Пример #9
0
        private void Btn_EnumCaptureAudio_Click(object sender, EventArgs e)
        {
            //Desativa o botão.
            Btn_EnumCaptureAudio.Enabled = false;

            //Cria a interface de enumeração de dispositivos.
            myEnumeradorDevices.Enumerador = new CarenMMDeviceEnumerator(CA_CLSCTX.CLSCTX_INPROC_SERVER);

            //Inicializa a coleção que vai conter a lista de dispositivos.
            myEnumeradorDevices.ColecaoDisposistivos = new CarenMMDeviceCollection();

            //Lista todos os dispositivos de renderização de áudio (ATIVOS) no sistema atual.
            //A coleção contém ponteiros para a interface IMMDevice(ICarenMMDevice) que pode ser ativada para uma das interface da WASAPI, como a ICarenAudioClient que configura
            //e inicializa o dispositivo final.
            CarenResult Resultado = myEnumeradorDevices.Enumerador.EnumAudioEndpoints(
                CA_EDataFlow.eCapture,                      //O tipo do dispositivo de áudio
                CA_DEVICE_STATE_XXX.CA_DEVICE_STATE_ACTIVE, //O estado do dispositivo a ser incluido na enumeração(Ativado, Desativado etc)
                myEnumeradorDevices.ColecaoDisposistivos);  //A coleção que vai receber os dispositivos.

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar enumerar os dispositivos de renderização ativos no sistema operacional. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Verifica se encontrou algum dispositivo
            Resultado = myEnumeradorDevices.ColecaoDisposistivos.GetCount(out uint OutCountDevices);

            //Verifica se obteve sucesso
            if (Resultado.StatusCode != ResultCode.SS_OK)
            {
                //A operação falhou.

                //Mostra uma mensagem de erro.
                ShowMensagem(
                    "Ocorreu uma falha ao tentar recuperar a quantidade de dispositivos enumerados. Mensagem de erro -> "
                    + Resultado.ObterMensagem((int)Resultado.HResult), true);

                //Sai do método
                goto Done;
            }

            //Verifica a quantidade
            if (OutCountDevices <= 0)
            {
                //Não há nenhum dispositivo com as caracteristicas dadas na enumeração disponivel.

                //Mostra uma mensagem de ino.
                ShowMensagem("Nenhum dispositivo de renderização de áudio ativo no sistema foi encontrado!");

                //Sai do laço.
                goto Done;
            }

            //Limpa a lista.
            Cbx_CaptureAudioDevices.Items.Clear();

            //Abre um for para recuperar o nome de cada dispositivo e adicionar no combobox
            for (uint i = 0; i < OutCountDevices; i++)
            {
                //Obtém o nome e adiciona na lista.
                Cbx_CaptureAudioDevices.Items.Add(ObterNomeDispositivoByIndex(i));
            }

            //Define o index zero do combobox.
            Cbx_CaptureAudioDevices.SelectedIndex = 0;

            Done :;
            //Descarta todas as interfaces utilizadas.
            SafeReleaseInterface(myEnumeradorDevices.ColecaoDisposistivos);
            SafeReleaseInterface(myEnumeradorDevices.Enumerador);

            //Chama o GC.
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            //Ativa novamente o botão
            Btn_EnumCaptureAudio.Enabled = true;
        }