⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_osx_source.cc

📁 这是用python语言写的一个数字广播的信号处理工具包。利用它
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* -*- c++ -*- *//* * Copyright 2006 Free Software Foundation, Inc. *  * This file is part of GNU Radio. * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. *  * GNU Radio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with GNU Radio; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#define _USE_OMNI_THREADS_#include <audio_osx_source.h>#include <gr_io_signature.h>#include <stdexcept>#include <audio_osx.h>#define _OSX_AU_DEBUG_ 0#define _OSX_DO_LISTENERS_ 0void PrintStreamDesc (AudioStreamBasicDescription *inDesc){  if (inDesc == NULL) {    fprintf (stderr, "PrintStreamDesc: Can't print a NULL desc!\n");    return;  }  fprintf (stderr, "  Sample Rate        : %g\n", inDesc->mSampleRate);  fprintf (stderr, "  Format ID          : %4s\n", (char*)&inDesc->mFormatID);  fprintf (stderr, "  Format Flags       : %lX\n", inDesc->mFormatFlags);  fprintf (stderr, "  Bytes per Packet   : %ld\n", inDesc->mBytesPerPacket);  fprintf (stderr, "  Frames per Packet  : %ld\n", inDesc->mFramesPerPacket);  fprintf (stderr, "  Bytes per Frame    : %ld\n", inDesc->mBytesPerFrame);  fprintf (stderr, "  Channels per Frame : %ld\n", inDesc->mChannelsPerFrame);  fprintf (stderr, "  Bits per Channel   : %ld\n", inDesc->mBitsPerChannel);}// FIXME these should query some kind of user preferenceaudio_osx_source::audio_osx_source (int sample_rate,				    const std::string device_name,				    bool do_block,				    int channel_config,				    int max_sample_count)  : gr_sync_block ("audio_osx_source",		   gr_make_io_signature (0, 0, 0),		   gr_make_io_signature (0, 0, 0)),    d_deviceSampleRate (0.0), d_outputSampleRate (0.0),    d_channel_config (0),    d_inputBufferSizeFrames (0), d_inputBufferSizeBytes (0),    d_outputBufferSizeFrames (0), d_outputBufferSizeBytes (0),    d_deviceBufferSizeFrames (0), d_deviceBufferSizeBytes (0),    d_leadSizeFrames (0), d_leadSizeBytes (0),    d_trailSizeFrames (0), d_trailSizeBytes (0),    d_extraBufferSizeFrames (0), d_extraBufferSizeBytes (0),    d_queueSampleCount (0), d_max_sample_count (0),    d_n_AvailableInputFrames (0), d_n_ActualInputFrames (0),    d_n_user_channels (0), d_n_max_channels (0), d_n_deviceChannels (0),    d_do_block (do_block), d_passThrough (false),    d_internal (0), d_cond_data (0),    d_buffers (0),    d_InputAU (0), d_InputBuffer (0), d_OutputBuffer (0),    d_AudioConverter (0){  if (sample_rate <= 0) {    fprintf (stderr, "Invalid Sample Rate: %d\n", sample_rate);    throw std::invalid_argument ("audio_osx_source::audio_osx_source");  } else    d_outputSampleRate = (Float64) sample_rate;  if (channel_config <= 0 & channel_config != -1) {    fprintf (stderr, "Invalid Channel Config: %d\n", channel_config);    throw std::invalid_argument ("audio_osx_source::audio_osx_source");  } else if (channel_config == -1) {// no user input; try "device name" instead    int l_n_channels = (int) strtol (device_name.data(), (char **)NULL, 10);    if (l_n_channels == 0 & errno) {      fprintf (stderr, "Error Converting Device Name: %d\n", errno);      throw std::invalid_argument ("audio_osx_source::audio_osx_source");    }    if (l_n_channels <= 0)      channel_config = 2;    else      channel_config = l_n_channels;  }  d_channel_config = channel_config;// check that the max # of samples to store is valid  if (max_sample_count == -1)    max_sample_count = sample_rate;  else if (max_sample_count <= 0) {    fprintf (stderr, "Invalid Max Sample Count: %d\n", max_sample_count);    throw std::invalid_argument ("audio_osx_source::audio_osx_source");  }  d_max_sample_count = max_sample_count;#if _OSX_AU_DEBUG_  fprintf (stderr, "source(): max # samples = %ld\n", d_max_sample_count);#endif  OSStatus err = noErr;// create the default AudioUnit for input// Open the default input unit  ComponentDescription InputDesc;  InputDesc.componentType = kAudioUnitType_Output;  InputDesc.componentSubType = kAudioUnitSubType_HALOutput;  InputDesc.componentManufacturer = kAudioUnitManufacturer_Apple;  InputDesc.componentFlags = 0;  InputDesc.componentFlagsMask = 0;  Component comp = FindNextComponent (NULL, &InputDesc);  if (comp == NULL) {    fprintf (stderr, "FindNextComponent Error\n");    throw std::runtime_error ("audio_osx_source::audio_osx_source");  }  err = OpenAComponent (comp, &d_InputAU);  CheckErrorAndThrow (err, "OpenAComponent",		      "audio_osx_source::audio_osx_source");  UInt32 enableIO;// must enable the AUHAL for input and disable output // before setting the AUHAL's current device// Enable input on the AUHAL  enableIO = 1;  err = AudioUnitSetProperty (d_InputAU,			      kAudioOutputUnitProperty_EnableIO,			      kAudioUnitScope_Input,			      1, // input element			      &enableIO,			      sizeof (UInt32));  CheckErrorAndThrow (err, "AudioUnitSetProperty Input Enable",		      "audio_osx_source::audio_osx_source");// Disable output on the AUHAL  enableIO = 0;  err = AudioUnitSetProperty (d_InputAU,			      kAudioOutputUnitProperty_EnableIO,			      kAudioUnitScope_Output,			      0, // output element			      &enableIO,			      sizeof (UInt32));  CheckErrorAndThrow (err, "AudioUnitSetProperty Output Disable",		      "audio_osx_source::audio_osx_source");// set the default input device for our input AU  SetDefaultInputDeviceAsCurrent ();#if _OSX_DO_LISTENERS_// set up a listener if default hardware input device changes  err = AudioHardwareAddPropertyListener    (kAudioHardwarePropertyDefaultInputDevice,     (AudioHardwarePropertyListenerProc) HardwareListener,     this);  CheckErrorAndThrow (err, "AudioHardwareAddPropertyListener",		      "audio_osx_source::audio_osx_source");// Add a listener for any changes in the input AU's output stream// the function "UnitListener" will be called if the stream format// changes for whatever reason  err = AudioUnitAddPropertyListener    (d_InputAU,     kAudioUnitProperty_StreamFormat,     (AudioUnitPropertyListenerProc) UnitListener,     this);  CheckErrorAndThrow (err, "Adding Unit Property Listener",		      "audio_osx_source::audio_osx_source");#endif// Now find out if it actually can do input.  UInt32 hasInput = 0;  UInt32 dataSize = sizeof (hasInput);  err = AudioUnitGetProperty (d_InputAU,			      kAudioOutputUnitProperty_HasIO,			      kAudioUnitScope_Input,			      1,			      &hasInput,			      &dataSize);  CheckErrorAndThrow (err, "AudioUnitGetProperty HasIO",		      "audio_osx_source::audio_osx_source");  if (hasInput == 0) {    fprintf (stderr, "Selected Audio Device does not support Input.\n");    throw std::runtime_error ("audio_osx_source::audio_osx_source");  }// Set up a callback function to retrieve input from the Audio Device  AURenderCallbackStruct AUCallBack;  AUCallBack.inputProc = (AURenderCallback)(audio_osx_source::AUInputCallback);  AUCallBack.inputProcRefCon = this;  err = AudioUnitSetProperty (d_InputAU,			      kAudioOutputUnitProperty_SetInputCallback,			      kAudioUnitScope_Global,			      0,			      &AUCallBack,			      sizeof (AURenderCallbackStruct));  CheckErrorAndThrow (err, "AudioUnitSetProperty Input Callback",		      "audio_osx_source::audio_osx_source");  UInt32 propertySize;  AudioStreamBasicDescription asbd_device, asbd_client, asbd_user;// asbd_device: ASBD of the device that is creating the input data stream// asbd_client: ASBD of the client size (output) of the hardware device// asbd_user:   ASBD of the user's arguments// Get the Stream Format (device side)  propertySize = sizeof (asbd_device);  err = AudioUnitGetProperty (d_InputAU,			      kAudioUnitProperty_StreamFormat,			      kAudioUnitScope_Input,			      1,			      &asbd_device,			      &propertySize);  CheckErrorAndThrow (err, "AudioUnitGetProperty Device Input Stream Format",		      "audio_osx_source::audio_osx_source");#if _OSX_AU_DEBUG_  fprintf (stderr, "\n---- Device Stream Format ----\n" );  PrintStreamDesc (&asbd_device);#endif// Get the Stream Format (client side)  propertySize = sizeof (asbd_client);  err = AudioUnitGetProperty (d_InputAU,			      kAudioUnitProperty_StreamFormat,			      kAudioUnitScope_Output,			      1,			      &asbd_client,			      &propertySize);  CheckErrorAndThrow (err, "AudioUnitGetProperty Device Ouput Stream Format",		      "audio_osx_source::audio_osx_source");#if _OSX_AU_DEBUG_  fprintf (stderr, "\n---- Client Stream Format ----\n");  PrintStreamDesc (&asbd_client);#endif// Set the format of all the AUs to the input/output devices channel count// get the max number of input (& thus output) channels supported by// this device  d_n_max_channels = asbd_client.mChannelsPerFrame;// create the output io signature;// no input siganture to set (source is hardware)  set_output_signature (gr_make_io_signature (1,					      d_n_max_channels,					      sizeof (float)));// allocate the output circular buffer(s), one per channel  d_buffers = (circular_buffer<float>**) new    circular_buffer<float>* [d_n_max_channels];  UInt32 n_alloc = (UInt32) ceil ((double) d_max_sample_count);  for (UInt32 n = 0; n < d_n_max_channels; n++) {    d_buffers[n] = new circular_buffer<float> (n_alloc, false, false);  }  d_deviceSampleRate = asbd_device.mSampleRate;  d_n_deviceChannels = asbd_device.mChannelsPerFrame;// create an ASBD for the user's wants  asbd_user.mSampleRate = d_outputSampleRate;  asbd_user.mFormatID = kAudioFormatLinearPCM;  asbd_user.mFormatFlags = (kLinearPCMFormatFlagIsFloat |			    GR_PCM_ENDIANNESS |			    kLinearPCMFormatFlagIsPacked |			    kAudioFormatFlagIsNonInterleaved);  asbd_user.mBytesPerPacket = 4;  asbd_user.mFramesPerPacket = 1;  asbd_user.mBytesPerFrame = 4;  asbd_user.mChannelsPerFrame = d_n_max_channels;  asbd_user.mBitsPerChannel = 32;  if (d_deviceSampleRate == d_outputSampleRate) {// no need to do conversion if asbd_client matches user wants    d_passThrough = true;    d_leadSizeFrames = d_trailSizeFrames = 0L;  } else {    d_passThrough = false;// Create the audio converter    err = AudioConverterNew (&asbd_client, &asbd_user, &d_AudioConverter);    CheckErrorAndThrow (err, "AudioConverterNew",			"audio_osx_source::audio_osx_source");// Set the audio converter sample rate quality to "max" ...// requires more samples, but should sound nicer    UInt32 ACQuality = kAudioConverterQuality_Max;    propertySize = sizeof (ACQuality);    err = AudioConverterSetProperty (d_AudioConverter,				     kAudioConverterSampleRateConverterQuality,				     propertySize,				     &ACQuality);    CheckErrorAndThrow (err, "AudioConverterSetProperty "			"SampleRateConverterQuality",			"audio_osx_source::audio_osx_source");// set the audio converter's prime method to "pre",// which uses both leading and trailing frames// from the "current input".  All of this is handled// internally by the AudioConverter; we just supply// the frames for conversion.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -