Ignore:
Timestamp:
Jul 4, 2017 10:32:39 AM (7 years ago)
Author:
riza
Message:

Fix #1991: Support ALSA audio device volume setting.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-audiodev/alsa_dev.c

    r5452 r5616  
    4545#define MAX_SOUND_DEVICES_PER_CARD      5 
    4646#define MAX_DEVICES                     32 
     47#define MAX_MIX_NAME_LEN                64  
    4748 
    4849/* Set to 1 to enable tracing */ 
     
    9899    unsigned                     dev_cnt; 
    99100    pjmedia_aud_dev_info         devs[MAX_DEVICES]; 
     101    char                         pb_mixer_name[MAX_MIX_NAME_LEN]; 
    100102}; 
    101103 
     
    271273} 
    272274 
     275static void get_mixer_name(struct alsa_factory *af) 
     276{ 
     277    snd_mixer_t *handle; 
     278    snd_mixer_elem_t *elem; 
     279 
     280    if (snd_mixer_open(&handle, 0) < 0) 
     281        return; 
     282 
     283    if (snd_mixer_attach(handle, "default") < 0) { 
     284        snd_mixer_close(handle); 
     285        return; 
     286    } 
     287 
     288    if (snd_mixer_selem_register(handle, NULL, NULL) < 0) { 
     289        snd_mixer_close(handle); 
     290        return; 
     291    } 
     292 
     293    if (snd_mixer_load(handle) < 0) { 
     294        snd_mixer_close(handle); 
     295        return; 
     296    } 
     297 
     298    for (elem = snd_mixer_first_elem(handle); elem; 
     299         elem = snd_mixer_elem_next(elem)) 
     300    { 
     301        if (snd_mixer_selem_is_active(elem) && 
     302            snd_mixer_selem_has_playback_volume(elem)) 
     303        { 
     304            pj_ansi_strncpy(af->pb_mixer_name, snd_mixer_selem_get_name(elem), 
     305                            sizeof(af->pb_mixer_name)); 
     306            TRACE_((THIS_FILE, "Playback mixer name: %s", af->pb_mixer_name)); 
     307            break; 
     308        } 
     309    } 
     310    snd_mixer_close(handle); 
     311} 
     312 
    273313 
    274314/* Create ALSA audio driver. */ 
     
    356396        n++; 
    357397    } 
     398 
     399    /* Get the mixer name */ 
     400    get_mixer_name(af); 
    358401 
    359402    /* Install error handler after enumeration, otherwise we'll get many 
     
    893936                                       const void *value) 
    894937{ 
    895     PJ_UNUSED_ARG(strm); 
    896     PJ_UNUSED_ARG(cap); 
    897     PJ_UNUSED_ARG(value); 
     938    struct alsa_factory *af = ((struct alsa_stream*)strm)->af; 
     939 
     940    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && af->pb_mixer_name) { 
     941        int result; 
     942        pj_ssize_t min, max; 
     943        snd_mixer_t *handle; 
     944        snd_mixer_selem_id_t *sid; 
     945        snd_mixer_elem_t* elem; 
     946        unsigned vol = *(unsigned*)value; 
     947 
     948        if (snd_mixer_open(&handle, 0) < 0) 
     949            return PJMEDIA_EAUD_SYSERR; 
     950 
     951        if (snd_mixer_attach(handle, "default") < 0) 
     952            return PJMEDIA_EAUD_SYSERR; 
     953 
     954        if (snd_mixer_selem_register(handle, NULL, NULL) < 0) 
     955            return PJMEDIA_EAUD_SYSERR; 
     956 
     957        if (snd_mixer_load(handle) < 0) 
     958            return PJMEDIA_EAUD_SYSERR; 
     959 
     960        snd_mixer_selem_id_alloca(&sid); 
     961        snd_mixer_selem_id_set_index(sid, 0); 
     962        snd_mixer_selem_id_set_name(sid, af->pb_mixer_name); 
     963        elem = snd_mixer_find_selem(handle, sid); 
     964        if (!elem) 
     965            return PJMEDIA_EAUD_SYSERR; 
     966 
     967        snd_mixer_selem_get_playback_volume_range(elem, &min, &max); 
     968        if (snd_mixer_selem_set_playback_volume_all(elem, vol * max / 100) < 0) 
     969            return PJMEDIA_EAUD_SYSERR; 
     970 
     971        snd_mixer_close(handle); 
     972        return PJ_SUCCESS; 
     973    } 
    898974 
    899975    return PJMEDIA_EAUD_INVCAP; 
Note: See TracChangeset for help on using the changeset viewer.