audio HAL

enum output_type {
    OUTPUT_DEEP_BUF,      // deep PCM buffers output stream
    OUTPUT_LOW_LATENCY,   // low latency output stream
    OUTPUT_TOTAL
};


struct stream_out {
    struct audio_stream_out stream;

    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    struct pcm *pcm[PCM_TOTAL];
    struct pcm_config config;
    unsigned int pcm_device;   ///////////22222
    bool standby; /* true if all PCMs are inactive */
    audio_devices_t device;////1111
    audio_channel_mask_t channel_mask;
    /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
    audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
    bool muted;

    struct audio_device *dev;
};


struct audio_device {
    struct audio_hw_device hw_device;

    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    audio_devices_t out_device; //111111 same as stream_out.device for all active output streams
    audio_devices_t in_device;
    bool mic_mute;
    struct audio_route *ar;
    audio_source_t input_source;
    int cur_route_id;     /* current route ID: combination of input source
                           * and output device IDs */
    struct pcm *pcm_voice_out;
    struct pcm *pcm_sco_out;
    struct pcm *pcm_voice_in;
    struct pcm *pcm_sco_in;
/**
 * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode
 * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is
 * playing, and AUDIO_MODE_IN_CALL when a call is in progress.
 */
    audio_mode_t mode;   
    int in_call;
    float voice_volume;
    struct echo_reference_itfe *echo_reference;
/* RIL */
    struct ril_handle ril;
    struct stream_out *outputs[OUTPUT_TOTAL];

    volte_status_t volte_state;
    volte_status_t previous_volte_state;

    int     bluetooth_samplerate;
    bool    sco_in_turn_on;
    bool    sco_out_turn_on;
};



enum {
    OUT_DEVICE_SPEAKER,
    OUT_DEVICE_HEADSET,
    OUT_DEVICE_HEADPHONES,
    OUT_DEVICE_EARPIECE,
    OUT_DEVICE_BT_SCO,
    OUT_DEVICE_SPEAKER_AND_HEADSET,
    OUT_DEVICE_TAB_SIZE,           /* number of rows in route_configs[][] */
    OUT_DEVICE_NONE,
    OUT_DEVICE_CNT
};


struct audio_stream_out {
    struct audio_stream common;
    uint32_t (*get_latency)(const struct audio_stream_out *stream);
    int (*set_volume)(struct audio_stream_out *stream, float left, float right);
    ssize_t (*write)(struct audio_stream_out *stream, const void* buffer,
                     size_t bytes);

    int (*get_render_position)(const struct audio_stream_out *stream,
                               uint32_t *dsp_frames);
    int (*get_next_write_timestamp)(const struct audio_stream_out *stream,
                                    int64_t *timestamp);
    int (*set_callback)(struct audio_stream_out *stream,
            stream_callback_t callback, void *cookie);
    int (*pause)(struct audio_stream_out* stream);
    int (*resume)(struct audio_stream_out* stream);
    int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type );
    int (*flush)(struct audio_stream_out* stream);

    int (*get_presentation_position)(const struct audio_stream_out *stream,
                               uint64_t *frames, struct timespec *timestamp);
};

hardware/libhardware/include/hardware/audio.h
typedef struct audio_stream_out audio_stream_out_t;
/* common audio stream parameters and operations */ struct audio_stream { uint32_t (*get_sample_rate)(const struct audio_stream *stream); int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); size_t (*get_buffer_size)(const struct audio_stream *stream); audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); audio_format_t (*get_format)(const struct audio_stream *stream); int (*set_format)(struct audio_stream *stream, audio_format_t format); int (*standby)(struct audio_stream *stream); int (*dump)(const struct audio_stream *stream, int fd); audio_devices_t (*get_device)(const struct audio_stream *stream); int (*set_device)(struct audio_stream *stream, audio_devices_t device); int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); char * (*get_parameters)(const struct audio_stream *stream, const char *keys); int (*add_audio_effect)(const struct audio_stream *stream, effect_handle_t effect); int (*remove_audio_effect)(const struct audio_stream *stream, effect_handle_t effect); }; struct audio_hw_device { struct hw_device_t common; uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); int (*init_check)(const struct audio_hw_device *dev); int (*set_voice_volume)(struct audio_hw_device *dev, float volume); int (*set_master_volume)(struct audio_hw_device *dev, float volume); int (*get_master_volume)(struct audio_hw_device *dev, float *volume); /** * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is * playing, and AUDIO_MODE_IN_CALL when a call is in progress. */ int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); int (*set_mic_mute)(struct audio_hw_device *dev, bool state); int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); /* set/get global audio parameters */ int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); /* * Returns a pointer to a heap allocated string. The caller is responsible * for freeing the memory for it using free(). */ char * (*get_parameters)(const struct audio_hw_device *dev, const char *keys); size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, const struct audio_config *config); /** This method creates and opens the audio hardware output stream. * The "address" parameter qualifies the "devices" audio device type if needed. * The format format depends on the device type: * - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC" * - USB devices use the ALSA card and device numbers in the form "card=X;device=Y" * - Other devices may use a number or any other string. */ int (*open_output_stream)(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, audio_output_flags_t flags, struct audio_config *config, struct audio_stream_out **stream_out, const char *address); void (*close_output_stream)(struct audio_hw_device *dev, struct audio_stream_out* stream_out); }; device/samsung/mochagw01/audio/audio_route.c struct audio_route { struct mixer *mixer; unsigned int num_mixer_ctls; struct mixer_state *mixer_state; unsigned int mixer_path_size; unsigned int num_mixer_paths; struct mixer_path *mixer_path; }; struct mixer_path { char *name; unsigned int size; unsigned int length; struct mixer_setting *setting; }; static struct mixer_path *path_get_by_name(struct audio_route *ar, const char *name) { unsigned int i; for (i = 0; i < ar->num_mixer_paths; i++) if (strcmp(ar->mixer_path[i].name, name) == 0) return &ar->mixer_path[i]; return NULL; } enum player_type { PV_PLAYER = 1, SONIVOX_PLAYER = 2, STAGEFRIGHT_PLAYER = 3, NU_PLAYER = 4, TEST_PLAYER = 5, DLNA_PLAYER = 1001, DTCPIP_PLAYER = 1002, };

 

status_t AudioFlinger::openOutput(audio_module_handle_t module,
                                  audio_io_handle_t *output,
                                  audio_config_t *config,
                                  audio_devices_t *devices,
                                  const String8& address,
                                  uint32_t *latencyMs,
                                  audio_output_flags_t flags)
    sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
}


sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,
                                                            audio_io_handle_t *output,
                                                            audio_config_t *config,
                                                            audio_devices_t devices,
                                                            const String8& address,
                                                            audio_output_flags_t flags)
{
    status_t status = hwDevHal->open_output_stream(hwDevHal,
                                                   *output,
                                                   devices,
                                                   flags,
                                                   config,
                                                   &outStream,
                                                   address.string());

    audio_stream_out_t *outStream = NULL;
    mHardwareStatus = AUDIO_HW_IDLE;
    ALOGV("openOutput_l() openOutputStream returned output %p, sampleRate %d, Format %#x, "
            "channelMask %#x, status %d",
            outStream,
            config->sample_rate,
            config->format,
            config->channel_mask,
            status);

    if (status == NO_ERROR && outStream != NULL) {
        AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags);

//创建播放线程 PlaybackThread
*thread; if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { thread = new OffloadThread(this, outputStream, *output, devices); ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread); } else if ((flags & AUDIO_OUTPUT_FLAG_HIGH_RES_AUDIO) || (flags & AUDIO_OUTPUT_FLAG_DSEE)) { thread = new MixerThread(this, outputStream, *output, devices); ALOGV("openOutput() created mixer output for high res: ID %d thread %p", *output, thread); } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || !isValidPcmSinkFormat(config->format) || !isValidPcmSinkChannelMask(config->channel_mask)) { thread = new DirectOutputThread(this, outputStream, *output, devices); ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread); } else { thread = new MixerThread(this, outputStream, *output, devices); ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread); } mPlaybackThreads.add(*output, thread); return thread; } return 0; } //hardware/qcom/audio/hal/audio_hw.c  
//全局变量 audio模块指定用adev_open来处理audio的模块
static struct hw_module_methods_t hal_module_methods = { .open = adev_open, }; struct audio_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name = "QCOM Audio HAL", .author = "The Linux Foundation", .methods = &hal_module_methods, }, }; //hardware/qcom/audio/hal/audio_hw.c static int adev_open(const hw_module_t *module, const char *name, hw_device_t **device) { int i, ret; ALOGD("%s: enter", __func__); if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; pthread_mutex_lock(&adev_init_lock); if (audio_device_ref_count != 0){ *device = &adev->device.common; audio_device_ref_count++; ALOGD("%s: returning existing instance of adev", __func__); ALOGD("%s: exit", __func__); pthread_mutex_unlock(&adev_init_lock); return 0; } adev = calloc(1, sizeof(struct audio_device)); pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL); adev->device.common.tag = HARDWARE_DEVICE_TAG; adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->device.common.module = (struct hw_module_t *)module; adev->device.common.close = adev_close; adev->device.init_check = adev_init_check; adev->device.set_voice_volume = adev_set_voice_volume; adev->device.set_master_volume = adev_set_master_volume; adev->device.get_master_volume = adev_get_master_volume; adev->device.set_master_mute = adev_set_master_mute; adev->device.get_master_mute = adev_get_master_mute; adev->device.set_mode = adev_set_mode; adev->device.set_mic_mute = adev_set_mic_mute; adev->device.get_mic_mute = adev_get_mic_mute; adev->device.set_parameters = adev_set_parameters; adev->device.get_parameters = adev_get_parameters; adev->device.get_input_buffer_size = adev_get_input_buffer_size; adev->device.open_output_stream = adev_open_output_stream; adev->device.close_output_stream = adev_close_output_stream; adev->device.open_input_stream = adev_open_input_stream; adev->device.close_input_stream = adev_close_input_stream; adev->device.dump = adev_dump; /* Set the default route before the PCM stream is opened */ adev->mode = AUDIO_MODE_NORMAL; adev->active_input = NULL; adev->primary_output = NULL; adev->out_device = AUDIO_DEVICE_NONE; adev->bluetooth_nrec = true; adev->acdb_settings = TTY_MODE_OFF; /* adev->cur_hdmi_channels = 0; by calloc() */ adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int)); voice_init(adev); list_init(&adev->usecase_list); adev->cur_wfd_channels = 2; pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; /* Loads platform specific libraries dynamically */ adev->platform = platform_init(adev); if (!adev->platform) { free(adev->snd_dev_ref_cnt); free(adev); ALOGE("%s: Failed to init platform data, aborting.", __func__); *device = NULL; pthread_mutex_unlock(&adev_init_lock); return -EINVAL; } adev->snd_card_status.state = SND_CARD_STATE_ONLINE; if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) { adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW); if (adev->visualizer_lib == NULL) { ALOGE("%s: DLOPEN failed for %s", __func__, VISUALIZER_LIBRARY_PATH); } else { ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH); adev->visualizer_start_output = (int (*)(audio_io_handle_t, int))dlsym(adev->visualizer_lib, "visualizer_hal_start_output"); adev->visualizer_stop_output = (int (*)(audio_io_handle_t, int))dlsym(adev->visualizer_lib, "visualizer_hal_stop_output"); } } audio_extn_listen_init(adev, adev->snd_card); if (access(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, R_OK) == 0) { adev->offload_effects_lib = dlopen(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, RTLD_NOW); if (adev->offload_effects_lib == NULL) { ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH); } else { ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH); adev->offload_effects_start_output = (int (*)(audio_io_handle_t, int))dlsym(adev->offload_effects_lib, "offload_effects_bundle_hal_start_output"); adev->offload_effects_stop_output = (int (*)(audio_io_handle_t, int))dlsym(adev->offload_effects_lib, "offload_effects_bundle_hal_stop_output"); } } if (access(OFFLOAD_EFFECTS_SONYBUNDLE_LIBRARY_PATH, R_OK) == 0) { adev->offload_sony_effects_lib = dlopen(OFFLOAD_EFFECTS_SONYBUNDLE_LIBRARY_PATH, RTLD_NOW); if (adev->offload_sony_effects_lib == NULL) { ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_EFFECTS_SONYBUNDLE_LIBRARY_PATH); } else { ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_EFFECTS_SONYBUNDLE_LIBRARY_PATH); adev->offload_sony_effects_start_output = (int (*)(audio_io_handle_t, int))dlsym(adev->offload_sony_effects_lib, "offload_effects_sonybundle_hal_start_output"); adev->offload_sony_effects_stop_output = (int (*)(audio_io_handle_t, int))dlsym(adev->offload_sony_effects_lib, "offload_effects_sonybundle_hal_stop_output"); } } *device = &adev->device.common; audio_device_ref_count++; pthread_mutex_unlock(&adev_init_lock); ALOGV("%s: exit", __func__); return 0; }

 AudioPolicyManager连接AudioPolicyService
AudioPolicyManager中:其并没有直接与AudioPolicyService连接,而是通过AudioPolicyCompatClient连接的
AudioPolicyClientInterface *mpClientInterface;    对应的就是AudioPolicyCompatClient

posted @ 2015-04-27 21:56  牧 天  阅读(2322)  评论(0编辑  收藏  举报