static int alsa_init (struct sound_device *sd) { const char *file; snd_pcm_t *handle; int err; /* Open the sound device. Default is "default". */ if (sd->file) file = sd->file; else file = DEFAULT_ALSA_SOUND_DEVICE; snd_lib_error_set_handler ((snd_lib_error_handler_t) snd_error_quiet); err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0); snd_lib_error_set_handler (NULL); if (err < 0) return 0; snd_pcm_close (handle); sd->fd = -1; sd->open = alsa_open; sd->close = alsa_close; sd->configure = alsa_configure; sd->choose_format = alsa_choose_format; sd->write = alsa_write; sd->period_size = alsa_period_size; return 1; }
/* API: refresh the device list */ static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f) { struct alsa_factory *af = (struct alsa_factory*)f; char **hints, **n; int err; TRACE_((THIS_FILE, "pjmedia_snd_init: Enumerate sound devices")); if (af->pool != NULL) { pj_pool_release(af->pool); af->pool = NULL; } af->pool = pj_pool_create(af->pf, "alsa_aud", 256, 256, NULL); af->dev_cnt = 0; /* Enumerate sound devices */ err = snd_device_name_hint(-1, "pcm", (void***)&hints); if (err != 0) return PJMEDIA_EAUD_SYSERR; /* Set a null error handler prior to enumeration to suppress errors */ snd_lib_error_set_handler(null_alsa_error_handler); n = hints; while (*n != NULL) { char *name = snd_device_name_get_hint(*n, "NAME"); if (name != NULL) { if (0 != strcmp("null", name)) add_dev(af, name); free(name); } n++; } /* Get the mixer name */ get_mixer_name(af); /* Install error handler after enumeration, otherwise we'll get many * error messages about invalid card/device ID. */ snd_lib_error_set_handler(alsa_error_handler); err = snd_device_name_free_hint((void**)hints); PJ_LOG(4,(THIS_FILE, "ALSA driver found %d devices", af->dev_cnt)); return PJ_SUCCESS; }
static int do_alsa_open(snd_rawmidi_t **handle_p, const char *plu_name, const char *def_dev) { char *dname = pcm_parse_params(config.snd_plugin_params, plu_name, device_name_param); const char *dev_name = dname ?: def_dev; int ret; snd_lib_error_set_handler(&alsa_log_handler); ret = midoalsa_open(handle_p, dev_name); /* reset back the error handler to not steal logs from * other subsystems, like audio */ snd_lib_error_set_handler(NULL); free(dname); return ret; }
AudioHardwareALSA::AudioHardwareALSA() : mALSADevice(0), mAcousticDevice(0) { snd_lib_error_set_handler(&ALSAErrorHandler); mMixer = new ALSAMixer; hw_module_t *module; int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); if (err == 0) { mALSADevice = (alsa_device_t *)device; mALSADevice->init(mALSADevice, mDeviceList); } else LOGE("ALSA Module could not be opened!!!"); } else LOGE("ALSA Module not found!!!"); err = hw_get_module(ACOUSTICS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ACOUSTICS_HARDWARE_NAME, &device); if (err == 0) mAcousticDevice = (acoustic_device_t *)device; else LOGE("Acoustics Module not found."); } }
/************************************************************************** * ALSA_MidiInit [internal] * * Initializes the MIDI devices information variables */ LONG ALSA_MidiInit(void) { #ifdef HAVE_ALSA static BOOL bInitDone = FALSE; snd_seq_client_info_t *cinfo; snd_seq_port_info_t *pinfo; if (bInitDone) return TRUE; TRACE("Initializing the MIDI variables.\n"); bInitDone = TRUE; /* try to open device */ if (midiOpenSeq(0) == -1) { return TRUE; } #if 0 /* Debug purpose */ snd_lib_error_set_handler(error_handler); #endif snd_seq_client_info_alloca(&cinfo); snd_seq_port_info_alloca(&pinfo); /* First, search for all internal midi devices */ snd_seq_client_info_set_client(cinfo, -1); while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) { snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) { int cap = snd_seq_port_info_get_capability(pinfo); int type = snd_seq_port_info_get_type(pinfo); if (type != SND_SEQ_PORT_TYPE_MIDI_GENERIC) ALSA_AddMidiPort(cinfo, pinfo, cap, type); } } /* Second, search for all external ports */ snd_seq_client_info_set_client(cinfo, -1); while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) { snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) { int cap = snd_seq_port_info_get_capability(pinfo); int type = snd_seq_port_info_get_type(pinfo); if (type == SND_SEQ_PORT_TYPE_MIDI_GENERIC) ALSA_AddMidiPort(cinfo, pinfo, cap, type); } } /* close file and exit */ midiCloseSeq(); TRACE("End\n"); #endif return TRUE; }
AlsaBackend::~AlsaBackend() { Log("%s\n",__PRETTY_FUNCTION__); snd_lib_error_set_handler(0); snd_config_update_free_global(); std::map<AudioStream*, AlsaThread*>::iterator iter; for (iter = p_alsathread.begin(); iter != p_alsathread.end(); iter++) { delete iter->second; delete iter->first; } }
static int laudio_alsa_init(laudio_status_cb cb, cfg_t *cfg_audio) { snd_lib_error_set_handler(logger_alsa); status_cb = cb; card_name = cfg_getstr(cfg_audio, "card"); mixer_name = cfg_getstr(cfg_audio, "mixer"); hdl = NULL; mixer_hdl = NULL; vol_elem = NULL; return 0; }
int laudio_init(laudio_status_cb cb) { snd_lib_error_set_handler(logger_alsa); status_cb = cb; card_name = cfg_getstr(cfg_getsec(cfg, "audio"), "card"); mixer_name = cfg_getstr(cfg_getsec(cfg, "audio"), "mixer"); hdl = NULL; mixer_hdl = NULL; vol_elem = NULL; return 0; }
static DECLCALLBACK(int) drvHostALSAAudioInit(PPDMIHOSTAUDIO pInterface) { NOREF(pInterface); LogFlowFuncEnter(); int rc = audioLoadAlsaLib(); if (RT_FAILURE(rc)) LogRel(("ALSA: Failed to load the ALSA shared library, rc=%Rrc\n", rc)); else { #ifdef DEBUG snd_lib_error_set_handler(drvHostALSAAudioErrorHandler); #endif } return rc; }
/* API: destroy factory */ static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f) { struct alsa_factory *af = (struct alsa_factory*)f; if (af->pool) pj_pool_release(af->pool); if (af->base_pool) { pj_pool_t *pool = af->base_pool; af->base_pool = NULL; pj_pool_release(pool); } /* Restore handler */ snd_lib_error_set_handler(NULL); return PJ_SUCCESS; }
static void alsaspdifsink_class_init (AlsaSPDIFSinkClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; GstBaseSinkClass *gstbasesink_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; gstbasesink_class = (GstBaseSinkClass *) klass; gobject_class->set_property = alsaspdifsink_set_property; gobject_class->get_property = alsaspdifsink_get_property; gobject_class->dispose = alsaspdifsink_dispose; gobject_class->finalize = alsaspdifsink_finalize; gstelement_class->change_state = alsaspdifsink_change_state; gstelement_class->provide_clock = alsaspdifsink_provide_clock; gstbasesink_class->event = alsaspdifsink_event; gstbasesink_class->render = alsaspdifsink_render; gstbasesink_class->get_times = alsaspdifsink_get_times; gstbasesink_class->set_caps = alsaspdifsink_set_caps; #if 0 /* We ignore the device property anyway, so don't install it * we don't want the user supplying just any device string for us. * At most we might want a card number and an iec958.%d device name * to attempt */ g_object_class_install_property (gobject_class, PROP_DEVICE, g_param_spec_string ("device", "Device", "ALSA device, as defined in an asound configuration file", "default", G_PARAM_READWRITE)); #endif g_object_class_install_property (gobject_class, PROP_CARD, g_param_spec_int ("card", "Card", "ALSA card number for the SPDIF device to use", 0, G_MAXINT, 0, G_PARAM_READWRITE)); snd_lib_error_set_handler (ignore_alsa_err); }
AudioHardwareALSA::AudioHardwareALSA() : mALSADevice(0), mAcousticDevice(0) { snd_lib_error_set_handler(&ALSAErrorHandler); mMixer = new ALSAMixer; hw_module_t *module; int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); if (err == 0) { mALSADevice = (alsa_device_t *)device; mALSADevice->init(mALSADevice, mDeviceList); } else LOGE("ALSA Module could not be opened!!!"); } else LOGE("ALSA Module not found!!!"); err = hw_get_module(ACOUSTICS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ACOUSTICS_HARDWARE_NAME, &device); if (err == 0) mAcousticDevice = (acoustic_device_t *)device; else LOGE("Acoustics Module not found."); } mMutestate = true; //[LG_FW_P970_MERGE] - jungsoo1221.lee // 20100426 [email protected] Add the mic mute [START_LGE] }
static int open_alsa(audio_output_t *ao) { const char *pcm_name; snd_pcm_t *pcm=NULL; printf("open_alsa with %p", ao->userptr); #ifndef DEBUG if(0) snd_lib_error_set_handler(error_ignorer); #endif pcm_name = ao->device ? ao->device : "default"; if (snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0) < 0) { if(!0) printf("cannot open device %s", pcm_name); return -1; } ao->userptr = pcm; if (ao->format != -1) { /* we're going to play: initalize sample format */ return initialize_device(ao); } else { /* query mode; sample format will be set for each query */ return 0; } }
static gboolean plugin_init (GstPlugin * plugin) #endif // GSTREAMER_LITE { int err; #ifndef GSTREAMER_LITE if (!gst_element_register (plugin, "alsasrc", GST_RANK_PRIMARY, GST_TYPE_ALSA_SRC)) return FALSE; #endif // GSTREAMER_LITE if (!gst_element_register (plugin, "alsasink", GST_RANK_PRIMARY, GST_TYPE_ALSA_SINK)) return FALSE; #ifndef GSTREAMER_LITE if (!gst_element_register (plugin, "alsamidisrc", GST_RANK_PRIMARY, GST_TYPE_ALSA_MIDI_SRC)) return FALSE; #endif // GSTREAMER_LITE GST_DEBUG_CATEGORY_INIT (alsa_debug, "alsa", 0, "alsa plugins"); #ifdef ENABLE_NLS GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif err = snd_lib_error_set_handler (gst_alsa_error_wrapper); if (err != 0) GST_WARNING ("failed to set alsa error handler"); return TRUE; }
AlsaBackend::AlsaBackend() { Log("%s\n",__PRETTY_FUNCTION__); snd_lib_error_set_handler(alsa_error_handler); }
/*static*/ int alsa_init(cubeb ** context, char const * context_name) { cubeb * ctx; int r; int i; int fd[2]; pthread_attr_t attr; snd_pcm_t * dummy; assert(context); *context = NULL; pthread_mutex_lock(&cubeb_alsa_mutex); if (!cubeb_alsa_error_handler_set) { snd_lib_error_set_handler(silent_error_handler); cubeb_alsa_error_handler_set = 1; } pthread_mutex_unlock(&cubeb_alsa_mutex); ctx = calloc(1, sizeof(*ctx)); assert(ctx); ctx->ops = &alsa_ops; r = pthread_mutex_init(&ctx->mutex, NULL); assert(r == 0); r = pipe(fd); assert(r == 0); for (i = 0; i < 2; ++i) { fcntl(fd[i], F_SETFD, fcntl(fd[i], F_GETFD) | FD_CLOEXEC); fcntl(fd[i], F_SETFL, fcntl(fd[i], F_GETFL) | O_NONBLOCK); } ctx->control_fd_read = fd[0]; ctx->control_fd_write = fd[1]; /* Force an early rebuild when alsa_run is first called to ensure fds and nfds have been initialized. */ ctx->rebuild = 1; r = pthread_attr_init(&attr); assert(r == 0); r = pthread_attr_setstacksize(&attr, 256 * 1024); assert(r == 0); r = pthread_create(&ctx->thread, &attr, alsa_run_thread, ctx); assert(r == 0); r = pthread_attr_destroy(&attr); assert(r == 0); /* Open a dummy PCM to force the configuration space to be evaluated so that init_local_config_with_workaround can find and modify the default node. */ r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, NULL); if (r >= 0) { alsa_locked_pcm_close(dummy); } ctx->is_pa = 0; pthread_mutex_lock(&cubeb_alsa_mutex); ctx->local_config = init_local_config_with_workaround(CUBEB_ALSA_PCM_NAME); pthread_mutex_unlock(&cubeb_alsa_mutex); if (ctx->local_config) { ctx->is_pa = 1; r = alsa_locked_pcm_open(&dummy, SND_PCM_STREAM_PLAYBACK, ctx->local_config); /* If we got a local_config, we found a PA PCM. If opening a PCM with that config fails with EINVAL, the PA PCM is too old for this workaround. */ if (r == -EINVAL) { pthread_mutex_lock(&cubeb_alsa_mutex); snd_config_delete(ctx->local_config); pthread_mutex_unlock(&cubeb_alsa_mutex); ctx->local_config = NULL; } else if (r >= 0) { alsa_locked_pcm_close(dummy); } } *context = ctx; return CUBEB_OK; }
void CAESinkALSA::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) { /* ensure that ALSA has been initialized */ snd_lib_error_set_handler(sndLibErrorHandler); if(!snd_config || force) { if(force) snd_config_update_free_global(); snd_config_update(); } snd_config_t *config; snd_config_copy(&config, snd_config); /* Always enumerate the default device. * Note: If "default" is a stereo device, EnumerateDevice() * will automatically add "@" instead to enable surroundXX mangling. * We don't want to do that if "default" can handle multichannel * itself (e.g. in case of a pulseaudio server). */ EnumerateDevice(list, "default", "", config); void **hints; if (snd_device_name_hint(-1, "pcm", &hints) < 0) { CLog::Log(LOGINFO, "CAESinkALSA - Unable to get a list of devices"); return; } std::string defaultDescription; for (void** hint = hints; *hint != NULL; ++hint) { char *io = snd_device_name_get_hint(*hint, "IOID"); char *name = snd_device_name_get_hint(*hint, "NAME"); char *desc = snd_device_name_get_hint(*hint, "DESC"); if ((!io || strcmp(io, "Output") == 0) && name && strcmp(name, "null") != 0) { std::string baseName = std::string(name); baseName = baseName.substr(0, baseName.find(':')); if (strcmp(name, "default") == 0) { /* added already, but lets get the description if we have one */ if (desc) defaultDescription = desc; } else if (baseName == "front") { /* Enumerate using the surroundXX mangling */ /* do not enumerate basic "front", it is already handled * by the default "@" entry added in the very beginning */ if (strcmp(name, "front") != 0) EnumerateDevice(list, std::string("@") + (name+5), desc ? desc : name, config); } /* Do not enumerate "default", it is already enumerated above. */ /* Do not enumerate the sysdefault or surroundXX devices, those are * always accompanied with a "front" device and it is handled above * as "@". The below devices will be automatically used if available * for a "@" device. */ /* Ubuntu has patched their alsa-lib so that "defaults.namehint.extended" * defaults to "on" instead of upstream "off", causing lots of unwanted * extra devices (many of which are not actually routed properly) to be * found by the enumeration process. Skip them as well ("hw", "dmix", * "plughw", "dsnoop"). */ else if (baseName != "default" && baseName != "sysdefault" && baseName != "surround40" && baseName != "surround41" && baseName != "surround50" && baseName != "surround51" && baseName != "surround71" && baseName != "hw" && baseName != "dmix" && baseName != "plughw" && baseName != "dsnoop") { EnumerateDevice(list, name, desc ? desc : name, config); } } free(io); free(name); free(desc); } snd_device_name_free_hint(hints); /* set the displayname for default device */ if (!list.empty() && list[0].m_deviceName == "default") { /* If we have one from a hint (DESC), use it */ if (!defaultDescription.empty()) list[0].m_displayName = defaultDescription; /* Otherwise use the discovered name or (unlikely) "Default" */ else if (list[0].m_displayName.empty()) list[0].m_displayName = "Default"; } /* lets check uniqueness, we may need to append DEV or CARD to DisplayName */ /* If even a single device of card/dev X clashes with Y, add suffixes to * all devices of both them, for clarity. */ /* clashing card names, e.g. "NVidia", "NVidia_2" */ std::set<std::string> cardsToAppend; /* clashing basename + cardname combinations, e.g. ("hdmi","Nvidia") */ std::set<std::pair<std::string, std::string> > devsToAppend; for (AEDeviceInfoList::iterator it1 = list.begin(); it1 != list.end(); ++it1) { for (AEDeviceInfoList::iterator it2 = it1+1; it2 != list.end(); ++it2) { if (it1->m_displayName == it2->m_displayName && it1->m_displayNameExtra == it2->m_displayNameExtra) { /* something needs to be done */ std::string cardString1 = GetParamFromName(it1->m_deviceName, "CARD"); std::string cardString2 = GetParamFromName(it2->m_deviceName, "CARD"); if (cardString1 != cardString2) { /* card name differs, add identifiers to all devices */ cardsToAppend.insert(cardString1); cardsToAppend.insert(cardString2); continue; } std::string devString1 = GetParamFromName(it1->m_deviceName, "DEV"); std::string devString2 = GetParamFromName(it2->m_deviceName, "DEV"); if (devString1 != devString2) { /* device number differs, add identifiers to all such devices */ devsToAppend.insert(std::make_pair(it1->m_deviceName.substr(0, it1->m_deviceName.find(':')), cardString1)); devsToAppend.insert(std::make_pair(it2->m_deviceName.substr(0, it2->m_deviceName.find(':')), cardString2)); continue; } /* if we got here, the configuration is really weird, just append the whole device string */ it1->m_displayName += " (" + it1->m_deviceName + ")"; it2->m_displayName += " (" + it2->m_deviceName + ")"; } } } for (std::set<std::string>::iterator it = cardsToAppend.begin(); it != cardsToAppend.end(); ++it) { for (AEDeviceInfoList::iterator itl = list.begin(); itl != list.end(); ++itl) { std::string cardString = GetParamFromName(itl->m_deviceName, "CARD"); if (cardString == *it) /* "HDA NVidia (NVidia)", "HDA NVidia (NVidia_2)", ... */ itl->m_displayName += " (" + cardString + ")"; } } for (std::set<std::pair<std::string, std::string> >::iterator it = devsToAppend.begin(); it != devsToAppend.end(); ++it) { for (AEDeviceInfoList::iterator itl = list.begin(); itl != list.end(); ++itl) { std::string baseName = itl->m_deviceName.substr(0, itl->m_deviceName.find(':')); std::string cardString = GetParamFromName(itl->m_deviceName, "CARD"); if (baseName == it->first && cardString == it->second) { std::string devString = GetParamFromName(itl->m_deviceName, "DEV"); /* "HDMI #0", "HDMI #1" ... */ itl->m_displayNameExtra += " #" + devString; } } } }
/* API: refresh the device list */ static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f) { struct alsa_factory *af = (struct alsa_factory*)f; char **hints, **n; int err; TRACE_((THIS_FILE, "pjmedia_snd_init: Enumerate sound devices")); if (af->pool != NULL) { pj_pool_release(af->pool); af->pool = NULL; } af->pool = pj_pool_create(af->pf, "alsa_aud", 256, 256, NULL); af->dev_cnt = 0; /* Enumerate sound devices */ err = snd_device_name_hint(-1, "pcm", (void***)&hints); if (err != 0) return PJMEDIA_EAUD_SYSERR; /* Set a null error handler prior to enumeration to suppress errors */ snd_lib_error_set_handler(null_alsa_error_handler); n = hints; while (*n != NULL) { char *name = snd_device_name_get_hint(*n, "NAME"); char *desc = snd_device_name_get_hint(*n, "DESC"); if (name != NULL) { if (strncmp("null", name, 4) == 0 || strncmp("front", name, 5) == 0 || strncmp("rear", name, 4) == 0 || strncmp("side", name, 4) == 0 || strncmp("dmix", name, 4) == 0 || strncmp("dsnoop", name, 6) == 0 || strncmp("hw", name, 2) == 0 || strncmp("plughw", name, 6) == 0 || strncmp("center_lfe", name, 10) == 0 || strncmp("surround40", name, 10) == 0 || strncmp("surround41", name, 10) == 0 || strncmp("surround50", name, 10) == 0 || strncmp("surround51", name, 10) == 0 || strncmp("surround71", name, 10) == 0 || (strncmp("default", name, 7) == 0 && strstr(name, ":CARD=") != NULL)) { /* skip these devices, 'sysdefault' always contains the relevant information */ ; } else { add_dev(af, name, desc); } free(name); free(desc); } n++; } /* Install error handler after enumeration, otherwise we'll get many * error messages about invalid card/device ID. */ snd_lib_error_set_handler(alsa_error_handler); err = snd_device_name_free_hint((void**)hints); PJ_LOG(4,(THIS_FILE, "ALSA driver found %d devices", af->dev_cnt)); return PJ_SUCCESS; }
static void alsa_card_init(MSSndCard *obj){ AlsaData *ad=ms_new0(AlsaData,1); obj->data=ad; snd_lib_error_set_handler(alsa_error_log_handler); }
AudioHardwareALSA::AudioHardwareALSA() : mMixer(0), mMixerSpdif(0), mMixerSgtl5000(0), mALSADevice(0), mAcousticDevice(0) { snd_lib_error_set_handler(&ALSAErrorHandler); hw_module_t *module; char snd_sgtl5000[32], snd_spdif[32]; char **cardname = new char*[MAXCARDSNUM]; for (int i = 0; i < MAXCARDSNUM; i++) { cardname[i] = new char[128]; memset(cardname[i],0,128); } int id; int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); if (err == 0) { mALSADevice = (alsa_device_t *)device; mALSADevice->init(mALSADevice, mDeviceList); } else LOGE("ALSA Module could not be opened!!!"); } else LOGE("ALSA Module not found!!!"); /* found out sound cards in the system and new mixer controller for them*/ err = findSoundCards(cardname); if (err == 0) { for (id = 0; id < MAXCARDSNUM; id++) { if(cardname[id] && strstr(cardname[id],SPDIF)){ LOGD(" CARD NAME: %s ID %d", cardname[id],id); sprintf(snd_spdif,"hw:0%d",id); sprintf(snd_spdif,"hw:CARD=%d",id); mMixerSpdif = new ALSAMixer(snd_spdif); }else if (cardname[id] && strstr(cardname[id],SGTL5000)){ LOGD(" CARD NAME: %s ID %d", cardname[id],id); sprintf(snd_sgtl5000,"hw:0%d",id); sprintf(snd_sgtl5000,"hw:CARD=%d",id); mMixerSgtl5000 = new ALSAMixer(snd_sgtl5000); } } } else { LOGE("Don't find any Sound cards, use default"); mMixerSgtl5000 = new ALSAMixer("hw:00"); mMixerSpdif = new ALSAMixer("hw:00"); } for (int i = 0; i < MAXCARDSNUM; i++) { delete []cardname[i]; } delete []cardname; mCurCard = new char[128]; if (!mCurCard) LOGE("allocate memeory to store current sound card name fail"); memset(mCurCard,0,sizeof(mCurCard)); /* set current card as sgtl5000 default */ if(mMixerSgtl5000) { strcpy(mCurCard,SGTL5000); mMixer = mMixerSgtl5000; }else if(mMixerSpdif) { strcpy(mCurCard,SPDIF); mMixer = mMixerSpdif; } err = hw_get_module(ACOUSTICS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (err == 0) { hw_device_t* device; err = module->methods->open(module, ACOUSTICS_HARDWARE_NAME, &device); if (err == 0) mAcousticDevice = (acoustic_device_t *)device; else LOGE("Acoustics Module not found."); } }
static void laudio_alsa_deinit(void) { snd_lib_error_set_handler(NULL); }
/* open & setup audio device return: 1=success 0=fail */ static int init(int rate_hz, int channels, int format, int flags) { unsigned int alsa_buffer_time = 500000; /* 0.5 s */ unsigned int alsa_fragcount = 16; int err; int block; strarg_t device; snd_pcm_uframes_t chunk_size; snd_pcm_uframes_t bufsize; snd_pcm_uframes_t boundary; const opt_t subopts[] = { {"block", OPT_ARG_BOOL, &block, NULL}, {"device", OPT_ARG_STR, &device, str_maxlen}, {NULL} }; char alsa_device[ALSA_DEVICE_SIZE + 1]; // make sure alsa_device is null-terminated even when using strncpy etc. memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1); mp_msg(MSGT_AO,MSGL_V,"alsa-init: requested format: %d Hz, %d channels, %x\n", rate_hz, channels, format); alsa_handler = NULL; #if SND_LIB_VERSION >= 0x010005 mp_msg(MSGT_AO,MSGL_V,"alsa-init: using ALSA %s\n", snd_asoundlib_version()); #else mp_msg(MSGT_AO,MSGL_V,"alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); #endif snd_lib_error_set_handler(alsa_error_handler); ao_data.samplerate = rate_hz; ao_data.format = format; ao_data.channels = channels; switch (format) { case AF_FORMAT_S8: alsa_format = SND_PCM_FORMAT_S8; break; case AF_FORMAT_U8: alsa_format = SND_PCM_FORMAT_U8; break; case AF_FORMAT_U16_LE: alsa_format = SND_PCM_FORMAT_U16_LE; break; case AF_FORMAT_U16_BE: alsa_format = SND_PCM_FORMAT_U16_BE; break; case AF_FORMAT_AC3_LE: case AF_FORMAT_S16_LE: case AF_FORMAT_IEC61937_LE: alsa_format = SND_PCM_FORMAT_S16_LE; break; case AF_FORMAT_AC3_BE: case AF_FORMAT_S16_BE: case AF_FORMAT_IEC61937_BE: alsa_format = SND_PCM_FORMAT_S16_BE; break; case AF_FORMAT_U32_LE: alsa_format = SND_PCM_FORMAT_U32_LE; break; case AF_FORMAT_U32_BE: alsa_format = SND_PCM_FORMAT_U32_BE; break; case AF_FORMAT_S32_LE: alsa_format = SND_PCM_FORMAT_S32_LE; break; case AF_FORMAT_S32_BE: alsa_format = SND_PCM_FORMAT_S32_BE; break; case AF_FORMAT_U24_LE: alsa_format = SND_PCM_FORMAT_U24_3LE; break; case AF_FORMAT_U24_BE: alsa_format = SND_PCM_FORMAT_U24_3BE; break; case AF_FORMAT_S24_LE: alsa_format = SND_PCM_FORMAT_S24_3LE; break; case AF_FORMAT_S24_BE: alsa_format = SND_PCM_FORMAT_S24_3BE; break; case AF_FORMAT_FLOAT_LE: alsa_format = SND_PCM_FORMAT_FLOAT_LE; break; case AF_FORMAT_FLOAT_BE: alsa_format = SND_PCM_FORMAT_FLOAT_BE; break; case AF_FORMAT_MU_LAW: alsa_format = SND_PCM_FORMAT_MU_LAW; break; case AF_FORMAT_A_LAW: alsa_format = SND_PCM_FORMAT_A_LAW; break; default: alsa_format = SND_PCM_FORMAT_MPEG; //? default should be -1 break; } //subdevice parsing // set defaults block = 1; /* switch for spdif * sets opening sequence for SPDIF * sets also the playback and other switches 'on the fly' * while opening the abstract alias for the spdif subdevice * 'iec958' */ if (AF_FORMAT_IS_IEC61937(format)) { device.str = "iec958"; mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n", channels); } else /* in any case for multichannel playback we should select * appropriate device */ switch (channels) { case 1: case 2: device.str = "default"; mp_msg(MSGT_AO,MSGL_V,"alsa-init: setup for 1/2 channel(s)\n"); break; case 4: if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) // hack - use the converter plugin device.str = "plug:surround40"; else device.str = "surround40"; mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround40\n"); break; case 6: if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) device.str = "plug:surround51"; else device.str = "surround51"; mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n"); break; case 8: if (alsa_format == SND_PCM_FORMAT_FLOAT_LE) device.str = "plug:surround71"; else device.str = "surround71"; mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround71\n"); break; default: device.str = "default"; mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels); } device.len = strlen(device.str); if (subopt_parse(ao_subdevice, subopts) != 0) { print_help(); return 0; } parse_device(alsa_device, device.str, device.len); mp_msg(MSGT_AO,MSGL_V,"alsa-init: using device %s\n", alsa_device); if (!alsa_handler) { int open_mode = block ? 0 : SND_PCM_NONBLOCK; int isac3 = AF_FORMAT_IS_IEC61937(format); //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC mp_msg(MSGT_AO,MSGL_V,"alsa-init: opening device in %sblocking mode\n", block ? "" : "non-"); if ((err = try_open_device(alsa_device, open_mode, isac3)) < 0) { if (err != -EBUSY && !block) { mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_OpenInNonblockModeFailed); if ((err = try_open_device(alsa_device, 0, isac3)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err)); return 0; } } else { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err)); return 0; } } if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSetBlockMode, snd_strerror(err)); } else { mp_msg(MSGT_AO,MSGL_V,"alsa-init: device reopened in blocking mode\n"); } snd_pcm_hw_params_alloca(&alsa_hwparams); snd_pcm_sw_params_alloca(&alsa_swparams); // setting hw-parameters if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetInitialParameters, snd_strerror(err)); return 0; } err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetAccessType, snd_strerror(err)); return 0; } /* workaround for nonsupported formats sets default format to S16_LE if the given formats aren't supported */ if ((err = snd_pcm_hw_params_test_format(alsa_handler, alsa_hwparams, alsa_format)) < 0) { mp_msg(MSGT_AO,MSGL_INFO, MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format)); alsa_format = SND_PCM_FORMAT_S16_LE; if (AF_FORMAT_IS_AC3(ao_data.format)) ao_data.format = AF_FORMAT_AC3_LE; else if (AF_FORMAT_IS_IEC61937(ao_data.format)) ao_data.format = AF_FORMAT_IEC61937_LE; else ao_data.format = AF_FORMAT_S16_LE; } if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, alsa_format)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetFormat, snd_strerror(err)); return 0; } if ((err = snd_pcm_hw_params_set_channels_near(alsa_handler, alsa_hwparams, &ao_data.channels)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetChannels, snd_strerror(err)); return 0; } /* workaround for buggy rate plugin (should be fixed in ALSA 1.0.11) prefer our own resampler, since that allows users to choose the resampler, even per file if desired */ #if SND_LIB_VERSION >= 0x010009 if ((err = snd_pcm_hw_params_set_rate_resample(alsa_handler, alsa_hwparams, 0)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToDisableResampling, snd_strerror(err)); return 0; } #endif if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, &ao_data.samplerate, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSamplerate2, snd_strerror(err)); return 0; } bytes_per_sample = af_fmt2bits(ao_data.format) / 8; bytes_per_sample *= ao_data.channels; ao_data.bps = ao_data.samplerate * bytes_per_sample; if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, &alsa_buffer_time, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetBufferTimeNear, snd_strerror(err)); return 0; } if ((err = snd_pcm_hw_params_set_periods_near(alsa_handler, alsa_hwparams, &alsa_fragcount, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriods, snd_strerror(err)); return 0; } /* finally install hardware parameters */ if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetHwParameters, snd_strerror(err)); return 0; } // end setting hw-params // gets buffersize for control if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBufferSize, snd_strerror(err)); return 0; } else { ao_data.buffersize = bufsize * bytes_per_sample; mp_msg(MSGT_AO,MSGL_V,"alsa-init: got buffersize=%i\n", ao_data.buffersize); } if ((err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetPeriodSize, snd_strerror(err)); return 0; } else { mp_msg(MSGT_AO,MSGL_V,"alsa-init: got period size %li\n", chunk_size); } ao_data.outburst = chunk_size * bytes_per_sample; /* setting software parameters */ if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters, snd_strerror(err)); return 0; } #if SND_LIB_VERSION >= 0x000901 if ((err = snd_pcm_sw_params_get_boundary(alsa_swparams, &boundary)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBoundary, snd_strerror(err)); return 0; } #else boundary = 0x7fffffff; #endif /* start playing when one period has been written */ if ((err = snd_pcm_sw_params_set_start_threshold(alsa_handler, alsa_swparams, chunk_size)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStartThreshold, snd_strerror(err)); return 0; } /* disable underrun reporting */ if ((err = snd_pcm_sw_params_set_stop_threshold(alsa_handler, alsa_swparams, boundary)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStopThreshold, snd_strerror(err)); return 0; } #if SND_LIB_VERSION >= 0x000901 /* play silence when there is an underrun */ if ((err = snd_pcm_sw_params_set_silence_size(alsa_handler, alsa_swparams, boundary)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSilenceSize, snd_strerror(err)); return 0; } #endif if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters, snd_strerror(err)); return 0; } /* end setting sw-params */ mp_msg(MSGT_AO,MSGL_V,"alsa: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", ao_data.samplerate, ao_data.channels, (int)bytes_per_sample, ao_data.buffersize, snd_pcm_format_description(alsa_format)); } // end switch alsa_handler (spdif) alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams); return 1; } // end init
int main(int argc, char **argv) { int c; snd_seq_t *seq; int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0; int command = SUBSCRIBE; int list_perm = 0; int client; int list_subs = 0; snd_seq_port_subscribe_t *subs; snd_seq_addr_t sender, dest; #ifdef ENABLE_NLS setlocale(LC_ALL, ""); textdomain(PACKAGE); #endif while ((c = getopt_long(argc, argv, "dior:t:elx", long_option, NULL)) != -1) { switch (c) { case 'd': command = UNSUBSCRIBE; break; case 'i': command = LIST; list_perm |= LIST_INPUT; break; case 'o': command = LIST; list_perm |= LIST_OUTPUT; break; case 'e': exclusive = 1; break; case 'r': queue = atoi(optarg); convert_time = 1; convert_real = 1; break; case 't': queue = atoi(optarg); convert_time = 1; convert_real = 0; break; case 'l': list_subs = 1; break; case 'x': command = REMOVE_ALL; break; default: usage(); exit(1); } } if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { fprintf(stderr, _("can't open sequencer\n")); return 1; } snd_lib_error_set_handler(error_handler); switch (command) { case LIST: do_search_port(seq, list_perm, list_subs ? print_port_and_subs : print_port); snd_seq_close(seq); return 0; case REMOVE_ALL: remove_all_connections(seq); snd_seq_close(seq); return 0; } /* connection or disconnection */ if (optind + 2 > argc) { snd_seq_close(seq); usage(); exit(1); } if ((client = snd_seq_client_id(seq)) < 0) { snd_seq_close(seq); fprintf(stderr, _("can't get client id\n")); return 1; } /* set client info */ if (snd_seq_set_client_name(seq, "ALSA Connector") < 0) { snd_seq_close(seq); fprintf(stderr, _("can't set client info\n")); return 1; } /* set subscription */ if (snd_seq_parse_address(seq, &sender, argv[optind]) < 0) { snd_seq_close(seq); fprintf(stderr, _("invalid sender address %s\n"), argv[optind]); return 1; } if (snd_seq_parse_address(seq, &dest, argv[optind + 1]) < 0) { snd_seq_close(seq); fprintf(stderr, _("invalid destination address %s\n"), argv[optind + 1]); return 1; } snd_seq_port_subscribe_alloca(&subs); snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); snd_seq_port_subscribe_set_queue(subs, queue); snd_seq_port_subscribe_set_exclusive(subs, exclusive); snd_seq_port_subscribe_set_time_update(subs, convert_time); snd_seq_port_subscribe_set_time_real(subs, convert_real); if (command == UNSUBSCRIBE) { if (snd_seq_get_port_subscription(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("No subscription is found\n")); return 1; } if (snd_seq_unsubscribe_port(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("Disconnection failed (%s)\n"), snd_strerror(errno)); return 1; } } else { if (snd_seq_get_port_subscription(seq, subs) == 0) { snd_seq_close(seq); fprintf(stderr, _("Connection is already subscribed\n")); return 1; } if (snd_seq_subscribe_port(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("Connection failed (%s)\n"), snd_strerror(errno)); return 1; } } snd_seq_close(seq); return 0; }
int sa_stream_open(sa_stream_t *s) { snd_output_t* out; char* buf; size_t bufsz; snd_pcm_hw_params_t* hwparams; snd_pcm_sw_params_t* swparams; int dir; snd_pcm_uframes_t period; if (s == NULL) { return SA_ERROR_NO_INIT; } if (s->output_unit != NULL) { return SA_ERROR_INVALID; } pthread_mutex_lock(&sa_alsa_mutex); /* Turn off debug output to stderr */ snd_lib_error_set_handler(quiet_error_handler); if (snd_pcm_open(&s->output_unit, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { pthread_mutex_unlock(&sa_alsa_mutex); return SA_ERROR_NO_DEVICE; } if (snd_pcm_set_params(s->output_unit, #ifdef SA_LITTLE_ENDIAN SND_PCM_FORMAT_S16_LE, #else SND_PCM_FORMAT_S16_BE, #endif SND_PCM_ACCESS_RW_INTERLEAVED, s->n_channels, s->rate, 1, 500000) < 0) { snd_pcm_close(s->output_unit); s->output_unit = NULL; pthread_mutex_unlock(&sa_alsa_mutex); return SA_ERROR_NOT_SUPPORTED; } /* ugly alsa-pulse plugin detection */ snd_output_buffer_open(&out); snd_pcm_dump(s->output_unit, out); bufsz = snd_output_buffer_string(out, &buf); s->pulseaudio = bufsz >= strlen(ALSA_PA_PLUGIN) && strncmp(buf, ALSA_PA_PLUGIN, strlen(ALSA_PA_PLUGIN)) == 0; snd_output_close(out); snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_current(s->output_unit, hwparams); snd_pcm_hw_params_get_period_size(hwparams, &period, &dir); pthread_mutex_unlock(&sa_alsa_mutex); return SA_SUCCESS; }
ALSAPCMPlayer::ALSAPCMPlayer(boost::asio::io_service &_io_service) : io_service(_io_service) { snd_lib_error_set_handler(alsa_error_handler_stub); }