/// <summary> /// Cria o Source Node(Nó de entrada) para um determinado fluxo no arquivo a ser renderizado. /// </summary> /// <param name="Param_StreamDesc">O Descritor para o fluxo no arquivo carregado.</param> /// <param name="Param_OutNode">Retorna uma interface para o nó de entrada.</param> /// <returns></returns> public CarenResult CreateSourceNodeToTopology(ICarenMFStreamDescriptor Param_StreamDesc, out ICarenMFTopologyNode Param_OutNode) { //Variavel a ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Cria o nó de origem. Param_OutNode = new CarenMFTopologyNode(CA_MF_TOPOLOGY_TYPE.MF_TOPOLOGY_SOURCESTREAM_NODE); //Define os atributos no nó. Param_OutNode.SetUnknown(GUIDs_MFAttributes_TopologyNode.MF_TOPONODE_SOURCE, myMediaSession.SourceMidia); Param_OutNode.SetUnknown(GUIDs_MFAttributes_TopologyNode.MF_TOPONODE_PRESENTATION_DESCRIPTOR, myMediaSession.DescritorMidia); Param_OutNode.SetUnknown(GUIDs_MFAttributes_TopologyNode.MF_TOPONODE_STREAM_DESCRIPTOR, Param_StreamDesc); //Adiciona o nó a topologia. Resultado = myMediaSession.Topologia.AddNode(Param_OutNode); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar adicionar o nó de origem a topologia.", true); //Sai do método. goto Done; } Done :; //Retorna o resultado. return(Resultado); }
private void PanelRender_SizeChanged(object sender, EventArgs e) { //Sincroniza o acesso. lock (Obj_SyncVideoPos) { //Verifica se o vídeo está sendo reproduzido antes de realizar a operação. if (StatusPlayback == StatusRendering.Rendering) { //Pausa a Media Session. myMediaSession.MediaSession.Pause(); //Define a nova posicação dos retangulos do video. CarenResult Resultado = myMediaSession.DisplayPlaybackControl.SetVideoPosition(new CA_MFVideoNormalizedRect() { right = 1, bottom = 1 }, new CA_RECT() { Rigth = PanelRender.Width, Left = 0, Bottom = PanelRender.Height, Top = 0 }); //Repinta a superfice. myMediaSession.DisplayPlaybackControl.RepaintSuperfice(); //Inicia novamente a media session. myMediaSession.MediaSession.Start(null, new CA_PROPVARIANT() { vt = CA_VARTYPE.VT_EMPTY }); } } }
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); }
/// <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); }
/// <summary> /// Cria o Output Node(Nó de saída), node responsável pelo codificador de audio ou video para o fluxo no arquivo carregado. /// </summary> /// <param name="Param_Sink">Uma interface de ativação para um Media Sink(Dissipador/Decoder) que representa o SAR(Áudio) ou o EVR(Vídeo).</param> /// <param name="Param_OutNode">Retorna uma interface para o nó de saída.</param> /// <returns></returns> public CarenResult CreateOutputNodeToTopology(ICarenMFActivate Param_Sink, out ICarenMFTopologyNode Param_OutNode) { //Variavel a ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Cria o nó de destino. Param_OutNode = new CarenMFTopologyNode(CA_MF_TOPOLOGY_TYPE.MF_TOPOLOGY_OUTPUT_NODE); //Adiciona o Sink ao nó Resultado = Param_OutNode.SetObject(Param_Sink); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar adicionar o Sink ao nó de saida!", true); //Sai do método. goto Done; } //Adiciona o nó a topologia. Resultado = myMediaSession.Topologia.AddNode(Param_OutNode); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar adicionar o nó de saida a topologia.", true); //Sai do método. goto Done; } //Informa um atributo que indica que a Media Session para não desligar o objeto que pertence a este nó de topologia. Resultado = Param_OutNode.SetUINT32(GUIDs_MFAttributes_TopologyNode.MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, 1); // 1 - TRUE | 0 - FALSE Done :; //Retorna o resultado. return(Resultado); }
private void Btn_Stop_Click(object sender, EventArgs e) { if (StatusPlayback == StatusRendering.Rendering & StatusPlayback != StatusRendering.NoStarted) { //Chama o método para pausar a reprodução. CarenResult Resultado = myMediaSession.MediaSession.Stop(); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar parar a reprodução atual!", true); } } }
/// <summary> /// Define uma nova posição de reprodução da midia. /// </summary> /// <param name="Param_NovaPosition">O valor da nova posição de reprodução em unidades de 100 nanossegundos.</param> /// <returns></returns> public CarenResult DefinirNovaPosicaoReproducao(Int64 Param_NovaPosition) { //Variavel a ser retornada. CarenResult Resultado = ResultCode.ER_FAIL; //Variaveis CA_PROPVARIANT PropVar = new CA_PROPVARIANT() { vt = CA_VARTYPE.VT_I8, hVal = new CA_LARGE_INTEGER() { QuadPart = Param_NovaPosition } }; //Chama o método para definir a nova posição de reprodução. Resultado = myMediaSession.MediaSession.Start(null, PropVar); //Retorna o resultado. return(Resultado); }
/// <summary> /// Retorna o tempo atual de reprodução em unidades de 100 nanossegundos. /// </summary> /// <returns></returns> public Int64 ObterPosicaoRelogioApresentacao() { //Variavel a ser retornada. Int64 CurrentPosition = 0; //Chama o método para recuperar o tempo atual de reprodução. CarenResult Resultado = myMediaSession.RelogioApresentacao.GetTime(out CurrentPosition); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Define erro. CurrentPosition = -1; } //Retorna o resultado return(CurrentPosition); }
/// <summary> /// Retorna o tempo total da midia em unidades de 100 nanossegundos. /// </summary> /// <returns></returns> public UInt64 ObterTempoTotalMidia() { //Variavel a ser retornada. UInt64 TotalTimeRender = 0; //Obtém o tempo total da midia. CarenResult Resultado = myMediaSession.DescritorMidia.GetUINT64(GUIDs_MFAttributes_PresentationDescriptor.MF_PD_DURATION, out TotalTimeRender); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Define erro. TotalTimeRender = 0; } //Retorna o resultado. return(TotalTimeRender); }
/// <summary> /// O método responsável por chamar as funções para configurar os nós de entrada e saida para os fluxos do arquivo a ser renderizado. /// </summary> /// <returns></returns> public CarenResult ConfigurarTopologia() { //Variavel que vai retornar o resultado da operação. CarenResult Resultado = ResultCode.SS_OK; //Cria a topologia myMediaSession.Topologia = new CarenMFTopology(true); //Cria um for para criar os nós de topologia para os fluxos da midia carregada. for (uint i = 0; i < myMediaSession.TotalStreamMediaSource; i++) { //Chama o método para configurar os nós de entrada e saida. Resultado = Configurar_Nodes_Topologia(i); //Verifica se não houve erro. if (Resultado.StatusCode != ResultCode.SS_OK) { break; } } //Retorna o resultado. return(Resultado); }
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); }
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); }
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); }
/// <summary> /// Método responsável por configurar o Media Sink(Dissipador/Decoder) para o fluxo selecionado e conectar o nó de entra ao de saída. /// </summary> /// <param name="Param_Id">O ID do fluxo a ser criado o Media Sink adequado.</param> /// <returns></returns> public CarenResult Configurar_Nodes_Topologia(uint Param_Id) { //Variavel que vai retornar o resultado da operação. CarenResult Resultado = ResultCode.SS_OK; //Variaveis utilizadas. ICarenMFStreamDescriptor OutStreamIdDescriptor = null; ICarenMFActivate OutSinkActivator = null; ICarenMFTopologyNode OutSourceNode = null; ICarenMFTopologyNode OutOutputNode = null; //Recupera a interface para o descritor do fluxo no id. Resultado = myMediaSession.DescritorMidia.GetStreamDescriptorByIndex(Param_Id, out bool OutSelecionado, out OutStreamIdDescriptor); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar obter o descritor de fluxo para a midia carregada!", true); //Sai do método. goto Done; } //Verifica se está selecionado e configura. if (!OutSelecionado) { //Não está selecionado.. //Sai do método goto Done; } //Cria um ativador para o media sink CreateMediaSinkByStream(OutStreamIdDescriptor, out OutSinkActivator); //Cria e adiciona o nó de entrada. CreateSourceNodeToTopology(OutStreamIdDescriptor, out OutSourceNode); //Cria e adiciona o nó de saida. CreateOutputNodeToTopology(OutSinkActivator, out OutOutputNode); //Conecta o nó de entrada ao nó de saida. Resultado = OutSourceNode.ConnectOutput(0, OutOutputNode, 0); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar conectar o nó de entrada ao nó de saida!", true); //Sai do método. goto Done; } Done :; //Retorna o resultado. return(Resultado); }
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); }
/// <summary> /// Método responsável por recuperar as interfaces de controle da midia(Audio, Video). /// </summary> /// <returns></returns> public CarenResult ObterInterfacesControle() { //Variavel a ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Recupera a interface de controle da Audio Resultado = MFTFuncs._MFGetService(myMediaSession.MediaSession, GUIDs_MF_SERVICE_INTERFACES.MR_POLICY_VOLUME_SERVICE, GUIDs_InterfacesMediaFoundation.IID_IMFSimpleAudioVolume, myMediaSession.AudioVolumePlayback = new CarenMFSimpleAudioVolume()); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recuperar a interface de controle de volume!", true); //Sai do método. goto Done; } //Recupera a interface de controle de vídeo. Resultado = MFTFuncs._MFGetService(myMediaSession.MediaSession, GUIDs_MF_SERVICE_INTERFACES.MR_VIDEO_RENDER_SERVICE, GUIDs_InterfacesMediaFoundation.IID_IMFVideoDisplayControl, myMediaSession.DisplayPlaybackControl = new CarenMFVideoDisplayControl()); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recupera a interface de controle de video!", true); //Sai do método. goto Done; } //Recupera o relogio Associado. Resultado = myMediaSession.MediaSession.GetClock(out myMediaSession.Relogio); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recupera o relogio associado a reprodução!", true); //Sai do método. goto Done; } //Obtém o relogio de apresentação. myMediaSession.Relogio.ConsultarInterface(GUIDs_InterfacesMediaFoundation.IID_IMFPresentationClock, myMediaSession.RelogioApresentacao = new CarenMFPresentationClock(false)); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recupera o relogio de apresentação da mídia!", true); //Sai do método. goto Done; } Done :; //Retorna o resultado. return(Resultado); }
//Source Resolver Callback private CarenResult CallbackCreateMediaSource_OnInvoke(ICarenMFAsyncResult Param_AsyncResult) { //Variavel que vai ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Variaveis utilizadas. CA_MF_OBJECT_TYPE OutTypeObject = CA_MF_OBJECT_TYPE.MF_OBJECT_INVALID; //Conclui a operação assincrona. Resultado = myMediaSession.ResolvedorMidia.EndCreateObjectFromURL(Param_AsyncResult, out OutTypeObject, myMediaSession.SourceMidia = new CarenMFMediaSource()); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar concluir a operação assincrona de criação da mídia!", true); //Sai do método. goto Done; } //Cria o Presentation Source. Resultado = myMediaSession.SourceMidia.CreatePresentationDescriptor(out myMediaSession.DescritorMidia); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha criar o descritor de apresetação para a mídia carregada!", true); //Sai do método. goto Done; } //Obtém a quantidade de stream no media source. Resultado = myMediaSession.DescritorMidia.GetStreamDescriptorCount(out myMediaSession.TotalStreamMediaSource); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao obter a quantidade de fluxos na mídia carregada!", true); //Sai do método. goto Done; } //Chama o método para criar e configurar a topologia ConfigurarTopologia(); //Define a topologia na Sessao da mídia. Resultado = myMediaSession.MediaSession.SetTopology(CA_MFSESSION_SETTOPOLOGY_FLAGS.Zero, myMediaSession.Topologia); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao definir a topologia na sessao de mídia!", true); //Sai do método. goto Done; } //Obtém o tempo total da mídia. myMediaSession.TotalTimeMidiaNs = ObterTempoTotalMidia(); myMediaSession.TotalTimeMidiaSegundos = myMediaSession.TotalTimeMidiaNs / REFTIME_1_SEGUNDO; Done :; //Retorna o resultado. return(Resultado); }
//Media Session Callback private CarenResult CallbackMediaSession_OnInvoke(ICarenMFAsyncResult Param_AsyncResult) { //Variavel que vai ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Variaveis utilizadas. ICarenMFMediaEvent OutEvent = null; CA_MediaEventType OutEventType = CA_MediaEventType.MEUnknown; //Obtém o evento gerado. Resultado = myMediaSession.MediaSession.EndGetEvent(Param_AsyncResult, out OutEvent); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar obter o evento da media session!", true); //Sai do método. goto Done; } //Obtém o tipo do evento. Resultado = OutEvent.GetType(out OutEventType); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar obter o tipo do evento da media session!", true); //Sai do método. goto Done; } //Chama o método para processar o evento ProcessarEventoMediaSession(OutEventType, ref OutEvent); //Verifica se a media session não foi fechada antes de requisitar o proximo evento. if (StatusPlayback != StatusRendering.Closed) { //Chama o proximo evento na lista. Resultado = myMediaSession.MediaSession.BeginGetEvent(myMediaSession.CallbackMediaSession, null); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar solicitar o proximo evento assincrona da Media Session!", true); //Sai do método. goto Done; } } Done :; //Libera o ponteiro para o evento. SafeReleaseInterface(OutEvent); //Retorna o resultado. return(Resultado); }
private UInt64 REFTIME_1_SEGUNDO = (UInt64)Math.Pow(10, 7); //Valor que se refere a 1 segundo de mídia em unidades de 100 nanossegundos. #endregion #region Métodos de configuração /// <summary> /// Inicializa a configuração basica da Media Session, configura enventos e inicia a solicitação para a criação do arquivo de mídia de forma assincrona. /// </summary> /// <returns></returns> public CarenResult IniciarConfiguração() { //Variavel que vai retornar o resultado da operação. CarenResult Resultado = ResultCode.SS_OK; //Inicia a plataforma da Media Foundation. MFTFuncs._MFStartup(); //Cria uma instância da media session. myMediaSession.MediaSession = new CarenMFMediaSession(null); //Cria as interfaces de Callback. myMediaSession.CallbackMediaSession = new CarenMFAsyncCallback(true); myMediaSession.CallbackCreateMediaSource = new CarenMFAsyncCallback(true); //Configura os eventos da Media Session myMediaSession.CallbackMediaSession.OnInvoke += CallbackMediaSession_OnInvoke; myMediaSession.CallbackMediaSession.OnGetParameters += CallbackMediaSession_OnGetParameters; //Configura os eventos do Source Resolver. myMediaSession.CallbackCreateMediaSource.OnGetParameters += CallbackCreateMediaSource_OnGetParameters; myMediaSession.CallbackCreateMediaSource.OnInvoke += CallbackCreateMediaSource_OnInvoke; //Registra os eventos para receber as notificações. myMediaSession.CallbackMediaSession.RegistrarCallback(); myMediaSession.CallbackCreateMediaSource.RegistrarCallback(); //Inicia uma solicitação assíncrona para o proximo evento na fila para a Media Session. Resultado = myMediaSession.MediaSession.BeginGetEvent(myMediaSession.CallbackMediaSession, null); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar definir o callback na media session1", true); //Sai do método. goto Done; } //Define a url. myMediaSession.UrlMidia = Txb_Url.Text; //Define a handle da janela de video. myMediaSession.HandleVideoPlayback = PanelRender.Handle; //Cria o resolvedor de midia para criar o media source. myMediaSession.ResolvedorMidia = new CarenMFSourceResolver(true); //Chama o método para criar o Media Source a parti da url. Resultado = myMediaSession.ResolvedorMidia.BeginCreateObjectFromURL( myMediaSession.UrlMidia, CA_SOURCE_RESOLVER_FLAGS.MF_RESOLUTION_MEDIASOURCE, null, new CarenParamResolver <ICaren>(true), myMediaSession.CallbackCreateMediaSource, //Configura o Callback da fonte de midia. null); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar criar uma fonte de mídia para a URL informada!", true); //Sai do método. goto Done; } Done :; //Retorna o resultado. return(Resultado); }
private void ProcessarEventoMediaSession(CA_MediaEventType Param_EventType, ref ICarenMFMediaEvent Param_Event) { //Variaveis CarenResult Resultado = new CarenResult(ResultCode.ER_FAIL, false); //Verifica o tipo do evento. switch (Param_EventType) { case CA_MediaEventType.MEUnknown: break; case CA_MediaEventType.MEError: break; case CA_MediaEventType.MEExtendedType: break; case CA_MediaEventType.MENonFatalError: break; case CA_MediaEventType.MESessionUnknown: break; case CA_MediaEventType.MESessionTopologySet: break; case CA_MediaEventType.MESessionTopologiesCleared: break; case CA_MediaEventType.MESessionStarted: //Define que está renderizando. StatusPlayback = StatusRendering.Rendering; break; case CA_MediaEventType.MESessionPaused: //Define que está pausado. StatusPlayback = StatusRendering.Paused; break; case CA_MediaEventType.MESessionStopped: //Define que a sessão de mídia foi parada. StatusPlayback = StatusRendering.Stoped; //Chama o método para fechar a Media Session. Resultado = myMediaSession.MediaSession.Close(); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar fechar a Media Session.", true); } break; case CA_MediaEventType.MESessionClosed: //Define que a media session foi fechada. StatusPlayback = StatusRendering.Closed; //Chama o método para concluir a liberação de todas as interfaces. LiberarInterfaces(); break; case CA_MediaEventType.MESessionEnded: break; case CA_MediaEventType.MESessionRateChanged: break; case CA_MediaEventType.MESessionScrubSampleComplete: break; case CA_MediaEventType.MESessionCapabilitiesChanged: break; case CA_MediaEventType.MESessionTopologyStatus: { //Variaveis utilizadas. CA_MF_TOPOSTATUS OutStatusTopology = CA_MF_TOPOSTATUS.MF_TOPOSTATUS_INVALID; //Obtém o atributo que indica o status da topologia no evento. Resultado = Param_Event.GetUINT32(GUIDs_MFAttributes_Events.MF_EVENT_TOPOLOGY_STATUS, out uint OutStatus); //Verifica se obteve sucesso na operação. if (Resultado.StatusCode != ResultCode.SS_OK) { goto Done; } //Converte o status OutStatusTopology = (CA_MF_TOPOSTATUS)OutStatus; //Verifica o status da topologia. switch (OutStatusTopology) { case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_INVALID: //Topologia em estado invalido. break; case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_READY: //A topologia está pronta. //Chama o método para recuperar as interfaces de serviços que seram utilizadas. ObterInterfacesControle(); //Chama o método para iniciar a reprodução. Resultado = myMediaSession.MediaSession.Start(null, new CA_PROPVARIANT() { vt = CA_VARTYPE.VT_EMPTY }); //Verifica se obteve sucesso. if (Resultado.StatusCode != ResultCode.SS_OK) { //Ocorreu uma falha ao tentar iniciar a reprodução da midia. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar iniciar a reprodução da mídia!", true); //Sai do método goto Done; } break; case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_STARTED_SOURCE: //A topologia começou a ler os dados. break; case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_DYNAMIC_CHANGED: break; case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_SINK_SWITCHED: break; case CA_MF_TOPOSTATUS.MF_TOPOSTATUS_ENDED: //A topologia chegou ao fim. break; default: break; } } break; case CA_MediaEventType.MESessionNotifyPresentationTime: break; case CA_MediaEventType.MESessionStreamSinkFormatChanged: break; case CA_MediaEventType.MENewPresentation: break; default: break; } Done :; //Informa o evento gerado. Debug.WriteLine("Evento gerado: " + Param_EventType.ToString()); }
/// <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); }
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; }
/// <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(); }
/// <summary> /// Cria um Ativador para o Media Sink apropriado com base no descritor de fluxo. O ativador pode ser um (SAR - Streaming Audio Render) ou o EVR(Enhanced Video Renderer) /// </summary> /// <param name="Param_StreamDesc">O descritor do fluxo a ter o ativador de midia criado.</param> /// <param name="OutAtivador">Retorna o ativador de midia apropriado para o descritor de midia informado.</param> /// <returns></returns> public CarenResult CreateMediaSinkByStream(ICarenMFStreamDescriptor Param_StreamDesc, out ICarenMFActivate Param_OutAtivador) { //Variavel a ser retornada. CarenResult Resultado = ResultCode.SS_OK; //Variaveis utilizadas. ICarenMFMediaTypeHandler MediaTypeHandler = null; Param_OutAtivador = null; //Recupera o type handler para o descritor de fluxo. Resultado = Param_StreamDesc.GetMediaTypeHandler(out MediaTypeHandler); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recuperar o Type Handler para o descritor de fluxo informado.", true); //Sai do método. goto Done; } //Obtém o tipo principal da midia Resultado = MediaTypeHandler.GetMajorType(out _, out CA_MAJOR_MEDIA_TYPES OutTipoPrincipal); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar recupera o tipo principal da midia no desctitor de fluxo.", true); //Sai do método. goto Done; } //Verifica o tipo principal da midia e cria o ativador com base no valor. if (OutTipoPrincipal == CA_MAJOR_MEDIA_TYPES.TP_Audio) { //Cria um ativador para o media sink do SAR. Resultado = MFTFuncs._MFCreateAudioRendererActivate(Param_OutAtivador = new CarenMFActivate()); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar criar o SAR.", true); //Sai do método. goto Done; } } else if (OutTipoPrincipal == CA_MAJOR_MEDIA_TYPES.TP_Video) { //Cria um ativador para o media sink do EVR. Resultado = MFTFuncs._MFCreateVideoRendererActivate(myMediaSession.HandleVideoPlayback, Param_OutAtivador = new CarenMFActivate()); //Verifica se não houve erro if (Resultado.StatusCode != ResultCode.SS_OK) { //Falhou ao realizar a operação. //Chama uma mensagem de erro. ShowMensagem("Ocorreu uma falha ao tentar criar o EVR.", true); //Sai do método. goto Done; } } else { //Chama uma mensagem de erro. ShowMensagem("O tipo do fluxo principal não é suportado!!", true); //Sai do método. goto Done; } Done :; //Libera as interfaces. SafeReleaseInterface(MediaTypeHandler); //Retorna o resultado. return(Resultado); }