Beispiel #1
0
        public void EnviarAmostra(ref ICarenBuffer Param_Buffer, uint Param_CountAudioBytes)
        {
            //Sincroniza o acesso a lista que contém os buffers de áudio.
            lock (SyncList)
            {
                //Novo buffer a ser adicionado.
                ICarenBuffer NewBuffer = new CarenBuffer();

                //Cria o buffer com a quantidade de dados validos.
                NewBuffer.CreateBuffer(Param_CountAudioBytes);

                //Cópia os dados do buffer do dispositivo de áudio para a amostra atual.
                NewBuffer.Write(Param_Buffer, 0, Param_CountAudioBytes);

                //Reseta a posição do buffer.
                NewBuffer.SetPosition(0);

                //Define as informações.
                NewBuffer.TamanhoValido = Param_CountAudioBytes;
                NewBuffer.Tamanho       = Param_CountAudioBytes;

                //Adiciona na lista.
                ListaBuffersAudio.Add(NewBuffer);
            }
        }
Beispiel #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);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }