コード例 #1
0
/*----------------------------------------------------------------------
|       AlsaOutputModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
AlsaOutputModule_Probe(BLT_Module*              self, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input protocol should be PACKET and the */
            /* output protocol should be NONE              */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_PACKET) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_NONE)) {
                return BLT_FAILURE;
            }

            /* the input type should be unknown, or audio/pcm */
            if (!(constructor->spec.input.media_type->id == 
                  BLT_MEDIA_TYPE_ID_AUDIO_PCM) &&
                !(constructor->spec.input.media_type->id == 
                  BLT_MEDIA_TYPE_ID_UNKNOWN)) {
                return BLT_FAILURE;
            }

            /* the name should be 'alsa:<name>' */
            if (constructor->name == NULL ||
                !ATX_StringsEqualN(constructor->name, "alsa:", 4)) {
                return BLT_FAILURE;
            }

            /* always an exact match, since we only respond to our name */
            *match = BLT_MODULE_PROBE_MATCH_EXACT;

            ATX_LOG_FINE_1("probe ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
コード例 #2
0
/*----------------------------------------------------------------------
|   FileOutputModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
FileOutputModule_Probe(BLT_Module*              self, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input protocol should be STREAM_PUSH and the */
            /* output protocol should be NONE                   */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_NONE)) {
                return BLT_FAILURE;
            }

            /* we need a name */
            if (constructor->name == NULL) {
                return BLT_FAILURE;
            }

            /* the name needs to be file:<filename> */
            if (!ATX_StringsEqualN(constructor->name, "file:", 5)) {
                return BLT_FAILURE;
            }

            /* always an exact match, since we only respond to our name */
            *match = BLT_MODULE_PROBE_MATCH_EXACT;

            ATX_LOG_FINE_1("FileOutputModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
コード例 #3
0
/*----------------------------------------------------------------------
|    OsxAudioUnitsOutput_Create
+---------------------------------------------------------------------*/
static BLT_Result
OsxAudioUnitsOutput_Create(BLT_Module*              module,
                           BLT_Core*                core, 
                           BLT_ModuleParametersType parameters_type,
                           const void*              parameters, 
                           BLT_MediaNode**          object)
{
    OsxAudioUnitsOutput*      self;
    BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters;
    AudioDeviceID             audio_device_id = 0;
    AudioUnit                 audio_unit = NULL;
    Component                 component;
    ComponentDescription      component_desc;
    ComponentResult           result;
    BLT_Result                blt_result;
    
    /* check parameters */
    if (parameters == NULL || 
        parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) {
        return BLT_ERROR_INVALID_PARAMETERS;
    }

    /* parse the name */
    if (!ATX_StringsEqualN(constructor->name, "osxau:", 6)) {
        return BLT_ERROR_INTERNAL;
    }

    /* map the name into a device ID */
    blt_result = OsxAudioUnitsOutput_MapDeviceName(constructor->name+6, &audio_device_id);
    if (BLT_FAILED(blt_result)) return blt_result;
    
    /* get the default output audio unit */
    ATX_SetMemory(&component_desc, 0, sizeof(component_desc));
    component_desc.componentType         = kAudioUnitType_Output;
    component_desc.componentSubType      = audio_device_id?kAudioUnitSubType_HALOutput:kAudioUnitSubType_DefaultOutput;
    component_desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    component_desc.componentFlags        = 0;
    component_desc.componentFlagsMask    = 0;
    component = FindNextComponent(NULL, &component_desc);
    if (component == NULL) {
        ATX_LOG_WARNING("FindNextComponent failed");
        return BLT_FAILURE;
    }
    
    /* open the audio unit (we will initialize it later) */
    result = OpenAComponent(component, &audio_unit);
    if (result != noErr) {
        ATX_LOG_WARNING_1("OpenAComponent failed (%d)", (int)result);
        return BLT_FAILURE;
    }

    /* Since SnowLeopard, kAudioHardwarePropertyRunLoop points at the process's main thread.
       Since not all apps service a run loop on the main thread (like command-line apps), we
       need to set the run loop to NULL to tell the HAL to run its own thread for this.
       This is important in order for the HAL to receive events when, for example, the headphones
       are plugged in or out.
       NOTE: this was the default before SnowLeopard (10.6), so we only do this if we're 10.6 or
       after */
    {
        SInt32 major, minor;

        Gestalt(gestaltSystemVersionMajor, &major);
        Gestalt(gestaltSystemVersionMinor, &minor);
        if (major > 10 || (major == 10 && minor >= 6)) {
            ATX_LOG_INFO("configuring the HAL to use its own thread for the run loop");
            CFRunLoopRef null_loop =  NULL;
            AudioObjectPropertyAddress address = { kAudioHardwarePropertyRunLoop, 
                                                   kAudioObjectPropertyScopeGlobal, 
                                                   kAudioObjectPropertyElementMaster };
            AudioObjectSetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, sizeof(CFRunLoopRef), &null_loop);
        }
    }
    
    /* allocate memory for the object */
    self = ATX_AllocateZeroMemory(sizeof(OsxAudioUnitsOutput));
    if (self == NULL) {
        *object = NULL;
        return BLT_ERROR_OUT_OF_MEMORY;
    }

    /* construct the inherited object */
    BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core);

    /* construct the object */
    self->audio_device_id            = audio_device_id;
    self->audio_unit                 = audio_unit;
    self->media_type.sample_rate     = 0;
    self->media_type.channel_count   = 0;
    self->media_type.bits_per_sample = 0;

    /* create a lock */
    pthread_mutex_init(&self->lock, NULL);
    
    /* create the packet queue */
    {
        ATX_ListDataDestructor destructor = { NULL, OsxAudioUnitsOutput_QueueItemDestructor };
        ATX_List_CreateEx(&destructor, &self->packet_queue);
        self->max_packets_in_queue = BLT_OSX_AUDIO_UNITS_OUTPUT_DEFAULT_PACKET_QUEUE_SIZE;
    }
    
    /* setup the expected media type */
    BLT_PcmMediaType_Init(&self->expected_media_type);
    self->expected_media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE;

    /* setup interfaces */
    ATX_SET_INTERFACE_EX(self, OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode);
    ATX_SET_INTERFACE_EX(self, OsxAudioUnitsOutput, BLT_BaseMediaNode, ATX_Referenceable);
    ATX_SET_INTERFACE   (self, OsxAudioUnitsOutput, BLT_PacketConsumer);
    ATX_SET_INTERFACE   (self, OsxAudioUnitsOutput, BLT_OutputNode);
    ATX_SET_INTERFACE   (self, OsxAudioUnitsOutput, BLT_MediaPort);
    ATX_SET_INTERFACE   (self, OsxAudioUnitsOutput, BLT_VolumeControl);
    *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode);

    return BLT_SUCCESS;
}