Пример #1
0
int eDVBVolumecontrol::openMixer()
{
#ifdef HAVE_ALSA
	if (!mainVolume)
	{
		int err;
		char *card = "default";

		/* Perform the necessary pre-amble to start up ALSA Mixer */
		err = snd_mixer_open(&alsaMixerHandle, 0);
		if (err < 0)
		{
			eDebug("Mixer %s open error: %s", card, snd_strerror(err));
			return err;
		}
		err = snd_mixer_attach(alsaMixerHandle, card);
		if (err < 0)
		{
			eDebug("Mixer attach %s error: %s", card, snd_strerror(err));
			snd_mixer_close(alsaMixerHandle);
			alsaMixerHandle = NULL;
			return err;
		}
		err = snd_mixer_selem_register(alsaMixerHandle, NULL, NULL);
		if (err < 0)
		{
			eDebug("Mixer register error: %s", snd_strerror(err));
			snd_mixer_close(alsaMixerHandle);
			alsaMixerHandle = NULL;
			return err;
		}
		err = snd_mixer_load(alsaMixerHandle);
		if (err < 0)
		{
			eDebug("Mixer %s load error: %s", card, snd_strerror(err));
			snd_mixer_close(alsaMixerHandle);
			alsaMixerHandle = NULL;
			return err;
		}

		/* Set up Decoder 0 as the main volume control. */
		snd_mixer_selem_id_t *sid;
		snd_mixer_selem_id_alloca(&sid);
		snd_mixer_selem_id_set_name(sid, ALSA_VOLUME_MIXER);
		snd_mixer_selem_id_set_index(sid, 0);
		mainVolume = snd_mixer_find_selem(alsaMixerHandle, sid);
	}
	return mainVolume ? 0 : -1;
#else
	return open( AUDIO_DEV, O_RDWR );
#endif
}
Пример #2
0
int get_vol_mute(long* vol, int* mute) {
  snd_mixer_t* handle;

  int open_code = snd_mixer_open(&handle, 0);
  if (open_code != 0) return open_code;

  int attach_code = snd_mixer_attach(handle, "default");
  if (attach_code != 0) {
    snd_mixer_close(handle);
    return attach_code;
  }

  int register_code = snd_mixer_selem_register(handle, NULL, NULL);
  if (register_code != 0) {
    cleanup_handle(handle);
    return register_code;
  }

  int load_code = snd_mixer_load(handle);
  if (load_code != 0) {
    cleanup_handle(handle);
    return load_code;
  }

  snd_mixer_selem_id_t *sid;
  snd_mixer_selem_id_alloca(&sid);
  snd_mixer_selem_id_set_index(sid, 0);
  snd_mixer_selem_id_set_name(sid, "Master");
  snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
  if (elem == 0) {
    cleanup_handle(handle);
    return 1;
  }

  int vol_code = snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_UNKNOWN, vol);
  if (vol_code != 0) {
    cleanup_handle(handle);
    return vol_code;
  }

  int switch_code = snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_UNKNOWN, mute);
  if (switch_code != 0) {
    cleanup_handle(handle);
    return switch_code;
  }

  /* snd_mixer_selem_id_free(sid); */
  snd_mixer_detach(handle, "default");
  snd_mixer_close(handle);
  return 0;
}
Пример #3
0
snd_mixer_elem_t* AmeSystemSound::getMixerElem(snd_mixer_t *mixer, char *name, int index)
{
	snd_mixer_selem_id_t* selem_id;
	snd_mixer_elem_t* elem;
	snd_mixer_selem_id_alloca(&selem_id);
	
	if (index != -1)
		snd_mixer_selem_id_set_index(selem_id, index);
	if (name != NULL)
		snd_mixer_selem_id_set_name(selem_id, name);
	
	elem = snd_mixer_find_selem(mixer, selem_id);
	return elem;
}
Пример #4
0
/* Retrieve a mixer element by name
 *
 * \param mixer The mixer to search the element from
 * \param element_name The element name to search for */
snd_mixer_elem_t *mixer_get_element(snd_mixer_t *mixer, const char *element_name) {
    pa_assert(mixer);
    pa_assert(element_name);

    snd_mixer_selem_id_t *sid = NULL;
    snd_mixer_elem_t *mixer_element = NULL;

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_name(sid, element_name);
    snd_mixer_selem_id_set_index(sid, 0);

    mixer_element = snd_mixer_find_selem(mixer, sid);

    return mixer_element;
}
Пример #5
0
long AudioALSA::getVolume() const {
    snd_mixer_t* handle;
    snd_mixer_elem_t* elem;
    snd_mixer_selem_id_t* sid;

    // Open sound card
    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, this->mixIndex);
    snd_mixer_selem_id_set_name(sid, this->mixName.c_str());

    if (snd_mixer_open(&handle, 0) < 0) {
        throw std::runtime_error("Error while mixer channel \"" + mixName + "\" opening");
    }
    if (snd_mixer_attach(handle, this->card.c_str())) {
        snd_mixer_close(handle);
        throw std::runtime_error("Error while attaching soundcard \"" + card + "\" to mixer");
    }
    if (snd_mixer_selem_register(handle, NULL, NULL) < 0) {
        snd_mixer_close(handle);
        throw std::runtime_error("Error while mixer channel registering");
    }
    if (snd_mixer_load(handle) < 0) {
        snd_mixer_close(handle);
        throw std::runtime_error("Error while loading mixer elements");
    }
    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        snd_mixer_close(handle);
        throw std::runtime_error("Error while finding mixer element");
    }

	// Get sound volume
	long volume, vmin, vmax;
	snd_mixer_selem_get_playback_volume_range(elem, &vmin, &vmax);
	if (snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &volume) < 0) {
		snd_mixer_close(handle);
        throw std::runtime_error("Error while getting playback volume");
	}
	volume -= vmin;
	vmax -= vmin;
	volume = 100 * volume / vmax;

    snd_mixer_close(handle);

	return volume;
}
Пример #6
0
bool AlsaMixer::GetChannelSwitch( const char* channel, bool* on )
{
	bool success = false;
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid;
	snd_mixer_selem_id_alloca(&sid);

	snd_mixer_selem_id_set_index( sid, 0);
	snd_mixer_selem_id_set_name( sid, channel);
	elem = snd_mixer_find_selem(_handle, sid);
	if (!elem) {
		LOG( Logger::LOG_ERROR, "Unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
		goto end;
	}

	if( snd_mixer_selem_has_playback_switch(elem) )
	{
		for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) {
			int value;
			if (snd_mixer_selem_get_playback_switch(elem, (snd_mixer_selem_channel_id_t)chn, &value) >= 0)
			{
				*on = value != 0; 
				success = true;
				break;
			}
		}
	}else if( snd_mixer_selem_has_capture_switch(elem) )
	{
		for (int chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++) {
			int value;
			if (snd_mixer_selem_get_capture_switch(elem, (snd_mixer_selem_channel_id_t)chn, &value ) >= 0)
			{
				*on = value != 0; 
				success = true;
				break;
			}
		}
	}
	if( !success )
	{
		LOG( Logger::LOG_ERROR, "Error getting control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
	}
 end:
	return success;
}
Пример #7
0
/* API: set capability */
static pj_status_t alsa_stream_set_cap(pjmedia_aud_stream *strm,
				       pjmedia_aud_dev_cap cap,
				       const void *value)
{
    struct alsa_factory *af = ((struct alsa_stream*)strm)->af;

    if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && 
	pj_ansi_strlen(af->pb_mixer_name)) 
    {
	pj_ssize_t min, max;
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t* elem;
	unsigned vol = *(unsigned*)value;

	if (snd_mixer_open(&handle, 0) < 0)
	    return PJMEDIA_EAUD_SYSERR;

	if (snd_mixer_attach(handle, "default") < 0)
	    return PJMEDIA_EAUD_SYSERR;

	if (snd_mixer_selem_register(handle, NULL, NULL) < 0)
	    return PJMEDIA_EAUD_SYSERR;

	if (snd_mixer_load(handle) < 0)
	    return PJMEDIA_EAUD_SYSERR;

	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid, 0);
	snd_mixer_selem_id_set_name(sid, af->pb_mixer_name);
	elem = snd_mixer_find_selem(handle, sid);
	if (!elem)
	    return PJMEDIA_EAUD_SYSERR;

	snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
	if (snd_mixer_selem_set_playback_volume_all(elem, vol * max / 100) < 0)
	    return PJMEDIA_EAUD_SYSERR;

	snd_mixer_close(handle);
	return PJ_SUCCESS;
    }

    return PJMEDIA_EAUD_INVCAP;
}
Пример #8
0
sound_ops_t *
alsa_probe( int exact )
{
	snd_pcm_t *pcm;
	const char *name = alsa_devname(0);
	
	if( !snd_mixer_open(&alsa.mixer, 0) ) {
		snd_mixer_selem_id_t *selem_id;
		const char *s, *mixername = get_str_res("alsa.mixer");
		const char *devname = alsa_devname(1);
		int mixerindex=0;
		
		if( (s=get_str_res_ind("alsa.mixer", 0, 1)) )
			mixerindex = atoi(s);
		if( mixername )
			printm("Using ALSA mixer %s %d (mixerdevice '%s')\n",
			       mixername, mixerindex, devname );
		if( !mixername )
			mixername = "PCM";

		snd_mixer_selem_id_alloca( &selem_id );
		snd_mixer_selem_id_set_index( selem_id, mixerindex );
		snd_mixer_selem_id_set_name( selem_id, mixername );

		int err = snd_mixer_attach( alsa.mixer, devname )
			|| snd_mixer_selem_register( alsa.mixer, NULL, NULL )
			|| snd_mixer_load( alsa.mixer );
		if( !err )
			alsa.pcm_elem=snd_mixer_find_selem( alsa.mixer, selem_id );
		if( alsa.pcm_elem )
			snd_mixer_selem_set_playback_volume_range( alsa.pcm_elem, 0, 0xff );
	}
	if( !snd_pcm_open(&pcm, name, SND_PCM_STREAM_PLAYBACK, 1 * SND_PCM_NONBLOCK) )
		snd_pcm_close( pcm );
	else if( !exact )
		return NULL;
	else
		printm("ALSA device unavailable (will be used anyway)\n");

	printm("ALSA sound driver loaded (device '%s')\n", name);
	if( !alsa.pcm_elem )
		printm("ALSA: failed to setup mixer\n");
	return &alsa_driver_ops;
}
Пример #9
0
int audio_set_volume( long volume )
{
//    int infos[3];
//    int infos;
    long min, max;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    const char *card = "default";//Ensoniq AudioPCI
    const char *selem_name = "Master";
    char response[255] = { 0 };

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);
    snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

    snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
    snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);

    snd_mixer_close(handle);

    snprintf( response , 255 , "OK");

    sendVoid( ( void * )response , strlen( response ) );

    //Sending the info to the remote
//    infos[0] = CURRENTVOL;
//    infos[1] = ( int )volume;
//    infos[2] = END;

//    infos = CURRENTVOL;
//    sendVoid( ( void * )&infos , sizeof( infos ) );

//    infos = ( int )volume;
//    sendVoid( ( void * )&infos , sizeof( infos ) );

//    infos = END;
//    sendVoid( ( void * )&infos , sizeof( infos ) );
}
Пример #10
0
struct alsa_control_struct GetStruct(const char* card, const char* selem_name) {
    struct alsa_control_struct c_struct;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);
    snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
    c_struct.handle = handle;
    c_struct.elem = elem;

    return c_struct;
}
Пример #11
0
void SetAlsaMasterVolume(long volume)
{
	long min, max;
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	const char *card = "default";
	const char *selem_name = "Master";
	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, card);
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);
	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid, 0);
	snd_mixer_selem_id_set_name(sid, selem_name);
	snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
	snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
	snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);
	snd_mixer_close(handle);
}
Пример #12
0
static void set_headphones_plugged(int* plugged)
{
    snd_mixer_t *handle;
    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, Y50_CTL_NAME);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_t *headphone_sid;
    const char *headphone_selem_name = "Headphone";

    snd_mixer_selem_id_alloca(&headphone_sid);
    snd_mixer_selem_id_set_index(headphone_sid, 0);
    snd_mixer_selem_id_set_name(headphone_sid, headphone_selem_name);

    snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, headphone_sid);
    snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_MONO, plugged);

    snd_mixer_close(handle);
}
Пример #13
0
void VolumeControl::setupAlsa(){
    const char *card = "default";
    const char *selem_name = "Master";//or Master
    if(snd_mixer_open(&handle, 0) == 0 ) mixer_opened = true;
    if(mixer_opened){
        //std::cout << "Mixer Opened" << std::endl;
        snd_config_update_free_global();//should make valgrind STFU
        snd_mixer_attach(handle, card);
        snd_mixer_selem_register(handle, NULL, NULL);
        snd_mixer_load(handle);
        snd_mixer_selem_id_alloca(&sid);
        snd_mixer_selem_id_set_index(sid, 0);
        snd_mixer_selem_id_set_name(sid, selem_name);
        elem = snd_mixer_find_selem(handle, sid);
        snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
        //std::cout << "Min:" << min << " Max:" << max << std::endl;
        snd_config_update_free_global();//should make valgrind STFU
    }else{
        std::cout << "Failed to open mixer" << std::endl;
    }
}
Пример #14
0
/*
 * Class:     org_tritonus_lowlevel_alsa_AlsaMixerElement
 * Method:    open
 * Signature: (Lorg/tritonus/lowlevel/alsa/AlsaMixer;ILjava/lang/String;)I
 */
JNIEXPORT jint JNICALL
Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_open
(JNIEnv *env, jobject obj, jobject mixer, jint nIndex, jstring strName)
{
    snd_mixer_elem_t*	handle;
    snd_mixer_t*		mixerHandle;
    snd_mixer_selem_id_t*	id;
    int			nReturn;
    const char*		name;

    if (debug_flag) {
        (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_open(): begin\n");
    }
    mixerHandle = getMixerNativeHandle(env, mixer);
    snd_mixer_selem_id_alloca(&id);
    snd_mixer_selem_id_set_index(id, nIndex);

    name= (*env)->GetStringUTFChars(env, strName, NULL);
    if (name == NULL)
    {
        throwRuntimeException(env, "GetStringUTFChars() failed");
        return -1;
    }
    snd_mixer_selem_id_set_name(id, name);
    (*env)->ReleaseStringUTFChars(env, strName, name);
    handle = snd_mixer_find_selem(mixerHandle, id);
    if (handle == NULL)
    {
        nReturn = -1;
    }
    else
    {
        setHandle(env, obj, handle);
        nReturn = 0;
    }
    if (debug_flag) {
        (void) fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaMixerElement_open(): end\n");
    }
    return nReturn;
}
Пример #15
0
void GetAlsaMasterVolume(long *volume)
{
    long min, max;
    snd_mixer_t *handle;
    snd_mixer_selem_id_t *sid;
    const char *card = "default";
    const char *selem_name = "Master";

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_alloca(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);
    snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

    snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, volume);

    snd_mixer_close(handle);
}
Пример #16
0
AlsaMixer *AlsaMixer::create(Sound *m)
{
    AlsaMixer *alsa = new AlsaMixer(m);
    if (!alsa) {
        return nullptr;
    }

    snd_mixer_open(&alsa->m_handle, 0);
    snd_mixer_attach(alsa->m_handle, card);
    snd_mixer_selem_register(alsa->m_handle, NULL, NULL);
    snd_mixer_load(alsa->m_handle);

    snd_mixer_selem_id_alloca(&alsa->m_sid);
    snd_mixer_selem_id_set_index(alsa->m_sid, 0);
    snd_mixer_selem_id_set_name(alsa->m_sid, selem_name);
    alsa->m_elem = snd_mixer_find_selem(alsa->m_handle, alsa->m_sid);
    if (!alsa->m_elem) {
        delete alsa;
        return nullptr;
    }

    snd_mixer_selem_get_playback_volume_range(alsa->m_elem, &alsa->m_min, &alsa->m_max);
    return alsa;
}
Пример #17
0
void KplAudioSetMasterVolume(long left, long right)
{
	long min, max;
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	const char *card = "default";
	const char *selem_name = "Master";

	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, card);
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);

	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid, 0);
	snd_mixer_selem_id_set_name(sid, selem_name);
	snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

	snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
	snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, min + (left * (max - min)) / 256);
	snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, min + (right * (max - min)) / 256);

	snd_mixer_close(handle);
}
Пример #18
0
int main(int argc, char * argv[])
{
   int pos = 125;
   long min, max;
   long gpiodelay_value = 250;		// was 50

   snd_mixer_t *handle;
   snd_mixer_selem_id_t *sid;

   const char *card = "default";
   // Previous linux driver's mixer name
   //   const char *selem_name = "Playback Digital";
   //	const char *selem_name = "PCM";
   const char *selem_name = "Digital";	// Linux 4.1.6-v7+ #810
   int x, mute_state;
   long i, currentVolume;

   printf("IQaudIO.com Pi-DAC Volume Control support Rotary Encoder) v1.5 Aug 30th 2015\n\n");

   wiringPiSetup ();

   /* pull up is needed as encoder common is grounded */
   pinMode (ENCODER_A, INPUT);
   pullUpDnControl (ENCODER_A, PUD_UP);
   pinMode (ENCODER_B, INPUT);
   pullUpDnControl (ENCODER_B, PUD_UP);

   encoderPos = pos;

   // Setup ALSA access
   snd_mixer_open(&handle, 0);
   snd_mixer_attach(handle, card);
   snd_mixer_selem_register(handle, NULL, NULL);
   snd_mixer_load(handle);

   snd_mixer_selem_id_alloca(&sid);
   snd_mixer_selem_id_set_index(sid, 0);
   snd_mixer_selem_id_set_name(sid, selem_name);
   snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);

   snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
   if (DEBUG_PRINT) printf("Returned card VOLUME range - min: %ld, max: %ld\n", min, max);

   // Minimum given is mute, we need the first real value
   min++;

   // Get current volume
   if (x = snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &currentVolume))
   {
        printf("%d %s\n", x, snd_strerror(x));
   }
   else if (DEBUG_PRINT) printf("Current ALSA volume LEFT: %ld\n", currentVolume);

   if (x = snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &currentVolume))
   {
        printf("%d %s\n", x, snd_strerror(x));
   }
   else if (DEBUG_PRINT) printf("Current ALSA volume RIGHT: %ld\n", currentVolume);


   /* monitor encoder level changes */
   wiringPiISR (ENCODER_A, INT_EDGE_BOTH, &encoderPulse);
   wiringPiISR (ENCODER_B, INT_EDGE_BOTH, &encoderPulse);


   // Now sit and spin waiting for GPIO pins to go active...
   while (1)
   {
      if (encoderPos != pos)
      {
              // get current volume
	      if (x = snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &currentVolume))
              {
        		printf("%d %s\n", x, snd_strerror(x));
              }
	      else if (DEBUG_PRINT) printf(" Current ALSA volume: %ld\n", currentVolume);

              // Adjust for MUTE
	      if (currentVolume < min) 
              {
                        currentVolume = 0;
			if (DEBUG_PRINT) printf(" Current ALSA volume set to min: %ld\n", currentVolume);
              }

              // What way did the encoder go?
	      if (encoderPos > pos)
	      {
		         pos = encoderPos;
			 currentVolume = currentVolume + 10;
			 // Adjust for MAX volume
			 if (currentVolume > max) currentVolume = max;
		         if (DEBUG_PRINT) printf("Volume UP %d - %ld", pos, currentVolume);
	      }
	      else if (encoderPos < pos)
	      {
		         pos = encoderPos;
                         currentVolume = currentVolume - 10;
 
			 // Adjust for MUTE
			 if (currentVolume < min) currentVolume = 0;
		         if (DEBUG_PRINT) printf("Volume DOWN %d - %ld", pos, currentVolume);
	      }

              if (x = snd_mixer_selem_set_playback_volume_all(elem, currentVolume))
              {
                     printf(" ERROR %d %s\n", x, snd_strerror(x));
              } else if (DEBUG_PRINT) printf(" Volume successfully set to %ld using ALSA!\n", currentVolume);
	}

	// Check x times per second, MAY NEED TO ADJUST THS FREQUENCY FOR SOME ENCODERS */
	delay(gpiodelay_value); /* check pos x times per second */
   }

   // We never get here but should close the sockets etc. on exit.
   snd_mixer_close(handle);
}
Пример #19
0
static int init(int argc, char **argv) {
  const char *str;
  int value;

  int hardware_mixer = 0;

  config.audio_backend_latency_offset = 0;           // this is the default for ALSA
  config.audio_backend_buffer_desired_length = 6615; // default for alsa with a software mixer
  
  

  // get settings from settings file first, allow them to be overridden by command line options

  if (config.cfg != NULL) {
    /* Get the desired buffer size setting. */
    if (config_lookup_int(config.cfg, "alsa.audio_backend_buffer_desired_length_software", &value)) {
      if ((value < 0) || (value > 66150))
        die("Invalid alsa audio backend buffer desired length (software) \"%d\". It should be between 0 and "
            "66150, default is 6615",
            value);
      else {
        config.audio_backend_buffer_desired_length = value;
      }
    }
    
    /* Get the latency offset. */
    if (config_lookup_int(config.cfg, "alsa.audio_backend_latency_offset", &value)) {
      if ((value < -66150) || (value > 66150))
        die("Invalid alsa audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
            value);
      else
        config.audio_backend_latency_offset = value;
    }

    /* Get the Output Device Name. */
    if (config_lookup_string(config.cfg, "alsa.output_device", &str)) {
      alsa_out_dev = (char *)str;
    }


    /* Get the Mixer Type setting. */

    if (config_lookup_string(config.cfg, "alsa.mixer_type", &str)) {
      inform("The alsa mixer_type setting is deprecated and has been ignored. FYI, using the \"mixer_control_name\" setting automatically chooses a hardware mixer.");
    }
    

    /* Get the Mixer Device Name. */
    if (config_lookup_string(config.cfg, "alsa.mixer_device", &str)) {
      alsa_mix_dev = (char *)str;
    }

    /* Get the Mixer Control Name. */
    if (config_lookup_string(config.cfg, "alsa.mixer_control_name", &str)) {
      alsa_mix_ctrl = (char *)str;
      hardware_mixer = 1;
    }
  }

  optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
  argv--;     // so we shift the arguments to satisfy getopt()
  argc++;
  // some platforms apparently require optreset = 1; - which?
  int opt;
  while ((opt = getopt(argc, argv, "d:t:m:c:i:")) > 0) {
    switch (opt) {
    case 'd':
      alsa_out_dev = optarg;
      break;

    case 't':
      inform("The alsa backend -t option is deprecated and has been ignored. FYI, using the -c option automatically chooses a hardware mixer.");
      break;

    case 'm':
      alsa_mix_dev = optarg;
      break;
    case 'c':
      alsa_mix_ctrl = optarg;
      hardware_mixer = 1;
      break;
    case 'i':
      alsa_mix_index = strtol(optarg, NULL, 10);
      break;
    default:
      help();
      die("Invalid audio option -%c specified", opt);
    }
  }

  if (optind < argc)
    die("Invalid audio argument: %s", argv[optind]);
  
  debug(1,"Output device name is \"%s\".",alsa_out_dev);

  if (!hardware_mixer)
    return 0;

  if (alsa_mix_dev == NULL)
    alsa_mix_dev = alsa_out_dev;

  int ret = 0;
  
  snd_mixer_selem_id_alloca(&alsa_mix_sid);
  snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
  snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);

  if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0)
    die("Failed to open mixer");
  debug(1,"Mixer device name is \"%s\".",alsa_mix_dev);
  if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0)
    die("Failed to attach mixer");
  if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0)
    die("Failed to register mixer element");

  ret = snd_mixer_load(alsa_mix_handle);
  if (ret < 0)
    die("Failed to load mixer element");
  
  debug(1,"Mixer Control name is \"%s\".",alsa_mix_ctrl);
    
  alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);    
  if (!alsa_mix_elem)
    die("Failed to find mixer element");

 
  if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) < 0)
    debug(1, "Can't read mixer's [linear] min and max volumes.");
  else {
    if (snd_mixer_selem_get_playback_dB_range (alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {

      audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
      audio_alsa.parameters = &parameters; // likewise the parameters stuff
      if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
        // Raspberry Pi does this
        debug(1, "Lowest dB value is a mute.");
        if (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv + 1,
                                                &alsa_mix_mindb) == 0)
          debug(1, "Can't get dB value corresponding to a \"volume\" of 1.");
      }
      debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
            (1.0 * alsa_mix_maxdb) / 100.0);
      if (config.volume_range_db) {
        long suggested_alsa_min_db = alsa_mix_maxdb - (long)trunc(config.volume_range_db*100);
        if (suggested_alsa_min_db > alsa_mix_mindb)
          alsa_mix_mindb = suggested_alsa_min_db;
        else
          inform("The volume_range_db setting, %f is greater than the native range of the mixer %f, so it is ignored.",config.volume_range_db,(alsa_mix_maxdb-alsa_mix_mindb)/100.0);
      }else{

        if(config.isset_volume_min_db){
          long suggested_alsa_min_db = (long) trunc(config.volume_min_db * 100);
          if(suggested_alsa_min_db > alsa_mix_mindb){
            alsa_mix_mindb = suggested_alsa_min_db; 
          }
        }

        if(config.isset_volume_max_db){
          long suggested_alsa_max_db = (long) trunc(config.volume_max_db * 100);
          if(suggested_alsa_max_db < alsa_mix_maxdb){
            alsa_mix_maxdb = suggested_alsa_max_db;
          }
        }
        
      }
    } else {
      // use the linear scale and do the db conversion ourselves
      debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have a dB volume scale, so it can't be used.",alsa_mix_ctrl);
      /*
      debug(1, "Min and max volumes are %d and %d.",alsa_mix_minv,alsa_mix_maxv);
      alsa_mix_maxdb = 0;
      if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
        alsa_mix_mindb = -20*100*(log10(alsa_mix_maxv*1.0)-log10(alsa_mix_minv*1.0));
      else if (alsa_mix_maxv!=0)
        alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
      audio_alsa.volume = &linear_volume; // insert the linear volume function
      audio_alsa.parameters = &parameters; // likewise the parameters stuff
      debug(1,"Max and min dB calculated are %d and %d.",alsa_mix_maxdb,alsa_mix_mindb);
      */
     }
  }
  if (snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
    has_mute = 1;
    debug(1, "Has mute ability.");
  }
  return 0;
}
Пример #20
0
/* Controls the alsamixer atributes of GCW device */
void mixer_control(int mode, long *volume, long *min, long *max)
{
	snd_mixer_t *handle;
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t *elem;

	snd_mixer_selem_channel_id_t channel = SND_MIXER_SCHN_FRONT_LEFT;

	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, "default");
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);

	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid, 0);

	if (mode == VOLUME_GET || mode == VOLUME_SET) {
		snd_mixer_selem_id_set_name(sid, "Headphone");
		elem = snd_mixer_find_selem(handle, sid);
	
		if (mode == VOLUME_GET) {
			snd_mixer_selem_get_playback_volume(elem, channel, volume);
			snd_mixer_selem_get_playback_volume_range(elem, min, max);
		} else if (mode == VOLUME_SET) {
			printf("GCW: Volume set to %ld\n", *volume);
			snd_mixer_selem_set_playback_volume_all(elem, *volume);
		}

		/* adjust volume to Bypass too */
		snd_mixer_selem_id_set_name(sid, "Line In Bypass");
		elem = snd_mixer_find_selem(handle, sid);

		if (mode == VOLUME_SET) {
			printf("Line in Bypass: Volume set to %ld\n", *volume);
			snd_mixer_selem_set_playback_volume_all(elem, *volume);
		}

	} else if (mode == HEADPHONE_TURN_ON || mode == HEADPHONE_TURN_OFF) {
		snd_mixer_selem_id_set_name(sid, "Headphone Source");
		elem = snd_mixer_find_selem(handle, sid);

		if (mode == HEADPHONE_TURN_ON) {
			printf("Headphone Source: Line In\n");
			snd_mixer_selem_set_enum_item(elem, channel, 1);
		} else if (mode == HEADPHONE_TURN_OFF) {
			printf("Headphone Source: PCM\n");
			snd_mixer_selem_set_enum_item(elem, channel, 0);
		}

	} else if (mode == SPEAKER_TURN_ON || mode == SPEAKER_TURN_OFF) {
		snd_mixer_selem_id_set_name(sid, "Speakers");
		elem = snd_mixer_find_selem(handle, sid);

		if (mode == SPEAKER_TURN_ON) {
			printf("Speaker turned on\n");
			snd_mixer_selem_set_playback_switch_all(elem, 1);
		} else if (mode == SPEAKER_TURN_OFF) {
			printf("Speaker turned off\n");
			snd_mixer_selem_set_playback_switch_all(elem, 0);
		}

		snd_mixer_selem_id_set_name(sid, "Line Out Source");
		elem = snd_mixer_find_selem(handle, sid);

		if (mode == SPEAKER_TURN_ON) {
			printf("Line Out Source turned on\n");
			snd_mixer_selem_set_enum_item(elem, channel, 1);
		} else if (mode == SPEAKER_TURN_OFF) {
			printf("Line Out Source turned off\n");
			snd_mixer_selem_set_enum_item(elem, channel, 0);
		}
	} else if (mode == BYPASS_VERIFICATION) {
		// volume here means that the radio is running in background or not
		*volume = 0;

		unsigned int setting = 0;
		snd_mixer_selem_id_set_name(sid, "Headphone Source");
		elem = snd_mixer_find_selem(handle, sid);

		snd_mixer_selem_get_enum_item(elem, channel, &setting);

		// the headphone is turned on
		if (setting == 1) {
			*volume = 1;
			return;
		}

		snd_mixer_selem_id_set_name(sid, "Line Out Source");
		elem = snd_mixer_find_selem(handle, sid);

		snd_mixer_selem_get_enum_item(elem, channel, &setting);

		// if both headphone and speakers are off, return 0 in volume to tell the screen that we need 
		// to setup the radio
		*volume = setting == 1;
	}
}
Пример #21
0
int getvolume(long* left_volume, long* right_volume) {
	int ret = 0;

	snd_mixer_t* handle;
	snd_mixer_elem_t* elem;
	snd_mixer_selem_id_t* sid;

	static const char* mix_name = "Master";
	static const char* card = "default";
	static int mix_index = 0;

	snd_mixer_selem_id_alloca(&sid);

	//sets simple-mixer index and name
	snd_mixer_selem_id_set_index(sid, mix_index);
	snd_mixer_selem_id_set_name(sid, mix_name);

	if ((snd_mixer_open(&handle, 0)) < 0)
		return -1;
	if ((snd_mixer_attach(handle, card)) < 0) {
		snd_mixer_close(handle);
		return -2;
	}
	if ((snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
		snd_mixer_close(handle);
		return -3;
	}
	ret = snd_mixer_load(handle);
	if (ret < 0) {
		snd_mixer_close(handle);
		return -4;
	}
	elem = snd_mixer_find_selem(handle, sid);
	if (!elem) {
		snd_mixer_close(handle);
		return -5;
	}

	long minv;
	long  maxv;
	snd_mixer_selem_get_playback_volume_range (elem, &minv, &maxv);

	if(snd_mixer_selem_get_playback_volume(elem, 0, left_volume) < 0) {
		snd_mixer_close(handle);
		return -3;
	}

	/* make the value bound to 100 */
	*left_volume -= minv;
	maxv -= minv;
	minv = 0;
	*left_volume = 100 * (*left_volume) / maxv; // make the value bound from 0 to 100

	snd_mixer_selem_get_playback_volume_range (elem, &minv, &maxv);

	if(snd_mixer_selem_get_playback_volume(elem, 1, right_volume) < 0) {
		snd_mixer_close(handle);
		return -4;
	}

	/* make the value bound to 100 */
	*right_volume -= minv;
	maxv -= minv;
	minv = 0;
	*right_volume = 100 * (*right_volume) / maxv; // make the value bound from 0 to 100

	snd_mixer_close(handle);
	return 0;

}
Пример #22
0
void VolumeControl::init()
{
	//initialize audio mixer interface
#if defined (__APPLE__)
	#warning TODO: Not implemented for MacOS yet!!!
#elif defined(__linux__)
	//try to open mixer device
	if (mixerHandle == nullptr)
	{
		snd_mixer_selem_id_alloca(&mixerSelemId);
		//sets simple-mixer index and name
		snd_mixer_selem_id_set_index(mixerSelemId, mixerIndex);
		snd_mixer_selem_id_set_name(mixerSelemId, mixerName);
		//open mixer
		if (snd_mixer_open(&mixerHandle, 0) >= 0)
		{
			LOG(LogDebug) << "VolumeControl::init() - Opened ALSA mixer";
			//ok. attach to defualt card
			if (snd_mixer_attach(mixerHandle, mixerCard) >= 0)
			{
				LOG(LogDebug) << "VolumeControl::init() - Attached to default card";
				//ok. register simple element class
				if (snd_mixer_selem_register(mixerHandle, NULL, NULL) >= 0)
				{
					LOG(LogDebug) << "VolumeControl::init() - Registered simple element class";
					//ok. load registered elements
					if (snd_mixer_load(mixerHandle) >= 0)
					{
						LOG(LogDebug) << "VolumeControl::init() - Loaded mixer elements";
						//ok. find elements now
						mixerElem = snd_mixer_find_selem(mixerHandle, mixerSelemId);
						if (mixerElem != nullptr)
						{
							//wohoo. good to go...
							LOG(LogDebug) << "VolumeControl::init() - Mixer initialized";
						}
						else
						{
							LOG(LogError) << "VolumeControl::init() - Failed to find mixer elements!";
							snd_mixer_close(mixerHandle);
							mixerHandle = nullptr;
						}
					}
					else
					{
						LOG(LogError) << "VolumeControl::init() - Failed to load mixer elements!";
						snd_mixer_close(mixerHandle);
						mixerHandle = nullptr;
					}
				}
				else
				{
					LOG(LogError) << "VolumeControl::init() - Failed to register simple element class!";
					snd_mixer_close(mixerHandle);
					mixerHandle = nullptr;
				}
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to attach to default card!";
				snd_mixer_close(mixerHandle);
				mixerHandle = nullptr;
			}
		}
		else
		{
			LOG(LogError) << "VolumeControl::init() - Failed to open ALSA mixer!";
		}
	}
#elif defined(WIN32) || defined(_WIN32)
	//get windows version information
	OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)};
	::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer));
	//check windows version
	if(osVer.dwMajorVersion < 6)
	{
		//Windows older than Vista. use mixer API. open default mixer
		if (mixerHandle == nullptr)
		{
			if (mixerOpen(&mixerHandle, 0, NULL, 0, 0) == MMSYSERR_NOERROR)
			{
				//retrieve info on the volume slider control for the "Speaker Out" line
				MIXERLINECONTROLS mixerLineControls;
				mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
				mixerLineControls.dwLineID = 0xFFFF0000; //Id of "Speaker Out" line
				mixerLineControls.cControls = 1;
				//mixerLineControls.dwControlID = 0x00000000; //Id of "Speaker Out" line's volume slider
				mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; //Get volume control
				mixerLineControls.pamxctrl = &mixerControl;
				mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
				if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
				{
					LOG(LogError) << "VolumeControl::getVolume() - Failed to get mixer volume control!";
					mixerClose(mixerHandle);
					mixerHandle = nullptr;
				}
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to open mixer!";
			}
		}
	}
	else
	{
		//Windows Vista or above. use EndpointVolume API. get device enumerator
		if (endpointVolume == nullptr)
		{
			CoInitialize(nullptr);
			IMMDeviceEnumerator * deviceEnumerator = nullptr;
			CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
			if (deviceEnumerator != nullptr)
			{
				//get default endpoint
				IMMDevice * defaultDevice = nullptr;
				deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
				if (defaultDevice != nullptr)
				{
					//retrieve endpoint volume
					defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&endpointVolume);
					if (endpointVolume == nullptr)
					{
						LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint volume!";
					}
					//release default device. we don't need it anymore
					defaultDevice->Release();
				}
				else
				{
					LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint!";
				}
				//release device enumerator. we don't need it anymore
				deviceEnumerator->Release();
			}
			else
			{
				LOG(LogError) << "VolumeControl::init() - Failed to get audio endpoint enumerator!";
				CoUninitialize();
			}
		}
	}
#endif
}
Пример #23
0
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
    struct priv *p = ao->priv;
    snd_mixer_t *handle = NULL;
    switch (cmd) {
    case AOCONTROL_GET_MUTE:
    case AOCONTROL_SET_MUTE:
    case AOCONTROL_GET_VOLUME:
    case AOCONTROL_SET_VOLUME:
    {
        int err;
        snd_mixer_elem_t *elem;
        snd_mixer_selem_id_t *sid;

        long pmin, pmax;
        long get_vol, set_vol;
        float f_multi;

        if (!af_fmt_is_pcm(ao->format))
            return CONTROL_FALSE;

        snd_mixer_selem_id_alloca(&sid);

        snd_mixer_selem_id_set_index(sid, p->cfg_mixer_index);
        snd_mixer_selem_id_set_name(sid, p->cfg_mixer_name);

        err = snd_mixer_open(&handle, 0);
        CHECK_ALSA_ERROR("Mixer open error");

        err = snd_mixer_attach(handle, p->cfg_mixer_device);
        CHECK_ALSA_ERROR("Mixer attach error");

        err = snd_mixer_selem_register(handle, NULL, NULL);
        CHECK_ALSA_ERROR("Mixer register error");

        err = snd_mixer_load(handle);
        CHECK_ALSA_ERROR("Mixer load error");

        elem = snd_mixer_find_selem(handle, sid);
        if (!elem) {
            MP_VERBOSE(ao, "Unable to find simple control '%s',%i.\n",
                       snd_mixer_selem_id_get_name(sid),
                       snd_mixer_selem_id_get_index(sid));
            goto alsa_error;
        }

        snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax);
        f_multi = (100 / (float)(pmax - pmin));

        switch (cmd) {
        case AOCONTROL_SET_VOLUME: {
            ao_control_vol_t *vol = arg;
            set_vol = vol->left / f_multi + pmin + 0.5;

            err = snd_mixer_selem_set_playback_volume
                    (elem, SND_MIXER_SCHN_FRONT_LEFT, set_vol);
            CHECK_ALSA_ERROR("Error setting left channel");
            MP_DBG(ao, "left=%li, ", set_vol);

            set_vol = vol->right / f_multi + pmin + 0.5;

            err = snd_mixer_selem_set_playback_volume
                    (elem, SND_MIXER_SCHN_FRONT_RIGHT, set_vol);
            CHECK_ALSA_ERROR("Error setting right channel");
            MP_DBG(ao, "right=%li, pmin=%li, pmax=%li, mult=%f\n",
                   set_vol, pmin, pmax, f_multi);
            break;
        }
        case AOCONTROL_GET_VOLUME: {
            ao_control_vol_t *vol = arg;
            snd_mixer_selem_get_playback_volume
                (elem, SND_MIXER_SCHN_FRONT_LEFT, &get_vol);
            vol->left = (get_vol - pmin) * f_multi;
            snd_mixer_selem_get_playback_volume
                (elem, SND_MIXER_SCHN_FRONT_RIGHT, &get_vol);
            vol->right = (get_vol - pmin) * f_multi;
            MP_DBG(ao, "left=%f, right=%f\n", vol->left, vol->right);
            break;
        }
        case AOCONTROL_SET_MUTE: {
            bool *mute = arg;
            if (!snd_mixer_selem_has_playback_switch(elem))
                goto alsa_error;
            if (!snd_mixer_selem_has_playback_switch_joined(elem)) {
                snd_mixer_selem_set_playback_switch
                    (elem, SND_MIXER_SCHN_FRONT_RIGHT, !*mute);
            }
            snd_mixer_selem_set_playback_switch
                (elem, SND_MIXER_SCHN_FRONT_LEFT, !*mute);
            break;
        }
        case AOCONTROL_GET_MUTE: {
            bool *mute = arg;
            if (!snd_mixer_selem_has_playback_switch(elem))
                goto alsa_error;
            int tmp = 1;
            snd_mixer_selem_get_playback_switch
                (elem, SND_MIXER_SCHN_FRONT_LEFT, &tmp);
            *mute = !tmp;
            if (!snd_mixer_selem_has_playback_switch_joined(elem)) {
                snd_mixer_selem_get_playback_switch
                    (elem, SND_MIXER_SCHN_FRONT_RIGHT, &tmp);
                *mute &= !tmp;
            }
            break;
        }
        }
        snd_mixer_close(handle);
        return CONTROL_OK;
    }

    } //end switch
    return CONTROL_UNKNOWN;

alsa_error:
    if (handle)
        snd_mixer_close(handle);
    return CONTROL_ERROR;
}
Пример #24
0
/*
  Drawbacks. Sets volume on both channels but gets volume on one. Can be easily adapted.
 */
int audio_volume(audio_volume_action action, long* outvol) {
	int ret = 0;
	snd_mixer_t* handle;
	snd_mixer_elem_t* elem;
	snd_mixer_selem_id_t* sid;

	static const char* mix_name = "Master";
	static const char* card = "default";
	static int mix_index = 0;

	long pmin, pmax;
	long get_vol, set_vol;
	float f_multi;

	snd_mixer_selem_id_alloca(&sid);

	//sets simple-mixer index and name
	snd_mixer_selem_id_set_index(sid, mix_index);
	snd_mixer_selem_id_set_name(sid, mix_name);

	if ((snd_mixer_open(&handle, 0)) < 0)
		return -1;
	if ((snd_mixer_attach(handle, card)) < 0) {
		snd_mixer_close(handle);
		return -2;
	}
	if ((snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
		snd_mixer_close(handle);
		return -3;
	}
	ret = snd_mixer_load(handle);
	if (ret < 0) {
		snd_mixer_close(handle);
		return -4;
	}
	elem = snd_mixer_find_selem(handle, sid);
	if (!elem) {
		snd_mixer_close(handle);
		return -5;
	}

	long minv, maxv;

	snd_mixer_selem_get_playback_volume_range (elem, &minv, &maxv);
	fprintf(stderr, "Volume range <%li,%li>\n", minv, maxv);

	if(action == AUDIO_VOLUME_GET) {
		if(snd_mixer_selem_get_playback_volume(elem, 0, outvol) < 0) {
			snd_mixer_close(handle);
			return -6;
		}

		fprintf(stderr, "Get volume %li with status %i\n", *outvol, ret);
		/* make the value bound to 100 */
		*outvol -= minv;
		maxv -= minv;
		minv = 0;
		*outvol = 100 * (*outvol) / maxv; // make the value bound from 0 to 100
	}
	else if(action == AUDIO_VOLUME_SET) {
		if(*outvol < 0 || *outvol > VOLUME_BOUND) // out of bounds
			return -7;
		*outvol = (*outvol * (maxv - minv) / (100-1)) + minv;

		if(snd_mixer_selem_set_playback_volume(elem, 0, *outvol) < 0) {
			snd_mixer_close(handle);
			return -8;
		}
		if(snd_mixer_selem_set_playback_volume(elem, 1, *outvol) < 0) {
			snd_mixer_close(handle);
			return -9;
		}
		fprintf(stderr, "Set volume %li with status %i\n", *outvol, ret);
	}

	snd_mixer_close(handle);
	return 0;
	}
Пример #25
0
gboolean show_mixer(GtkWidget *widget, GdkEvent  *event, gpointer user_data)
{

  GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(win), "SIDE Mixer");
  gtk_container_set_border_width(GTK_CONTAINER(win), 10);
  gtk_window_resize(GTK_WINDOW(win), 150, 300);
  GdkScreen *screen = gdk_screen_get_default();

  fwin = win;

  g_timeout_add(100, check_focus, win);

  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
  GtkWidget *dsc = gtk_label_new("master");

  GtkAdjustment *adj = gtk_adjustment_new(50, 0, 100, 5, 0, 0);
  g_signal_connect(G_OBJECT(adj), "value-changed", G_CALLBACK(set_volume), NULL);
  GtkWidget     *scl = gtk_scale_new(GTK_ORIENTATION_VERTICAL, adj);
  gtk_scale_set_draw_value(GTK_SCALE(scl), FALSE);

  s_mute = gtk_toggle_button_new_with_label("mute");

  g_signal_connect(G_OBJECT(s_mute), "toggled", G_CALLBACK(set_mute), (gpointer) adj);


  gtk_box_pack_end(GTK_BOX(box), s_mute, FALSE, FALSE, 0);


  gtk_container_add(GTK_CONTAINER(box), dsc);
  gtk_box_pack_end(GTK_BOX(box), scl, TRUE, TRUE, 5);


    int x, y;
    gtk_window_get_size(GTK_WINDOW(win), &x, &y);
    gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
    gtk_window_move(GTK_WINDOW(win), gdk_screen_get_width(screen), gdk_screen_get_height(screen) - (y+25));



  gtk_container_add(GTK_CONTAINER(win), box);
  gtk_widget_show_all(win);


  snd_mixer_t *mix;
  snd_mixer_selem_id_t *sid;
  const char *card = "default";
  const char *selem_name = "Master";

  long val, max, min;

  snd_mixer_open(&mix, 0);
  snd_mixer_attach(mix, card);
  snd_mixer_selem_register(mix, NULL, NULL);
  snd_mixer_load(mix);

  snd_mixer_selem_id_alloca(&sid);
  snd_mixer_selem_id_set_index(sid, 0);
  snd_mixer_selem_id_set_name(sid, selem_name);
  snd_mixer_elem_t* elem = snd_mixer_find_selem(mix, sid);

  snd_mixer_selem_get_playback_volume_range(elem, &min, &max);

  snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO  , &val);
  gtk_adjustment_set_value(adj, 100 - (int)  100 * val / max);


  snd_mixer_close(mix);



  return FALSE;
}
Пример #26
0
static int init(int argc, char **argv) {
    int hardware_mixer = 0;

    optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
    argv--;     // so we shift the arguments to satisfy getopt()
    argc++;
    // some platforms apparently require optreset = 1; - which?
    int opt;
    while ((opt = getopt(argc, argv, "d:t:m:c:i:")) > 0) {
        switch (opt) {
            case 'd':
                alsa_out_dev = optarg;
                break;
            case 't':
                if (strcmp(optarg, "hardware") == 0)
                    hardware_mixer = 1;
                break;
            case 'm':
                alsa_mix_dev = optarg;
                break;
            case 'c':
                alsa_mix_ctrl = optarg;
                break;
            case 'i':
                alsa_mix_index = strtol(optarg, NULL, 10);
                break;
            default:
                help();
                die("Invalid audio option -%c specified", opt);
        }
    }

    if (optind < argc)
        die("Invalid audio argument: %s", argv[optind]);

    if (!hardware_mixer)
        return 0;

    if (alsa_mix_dev == NULL)
        alsa_mix_dev = alsa_out_dev;
    audio_alsa.volume = &volume;

    int ret = 0;
    long alsa_mix_maxv;

    snd_mixer_selem_id_alloca(&alsa_mix_sid);
    snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
    snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);

    if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0)
        die ("Failed to open mixer");
    if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0)
        die ("Failed to attach mixer");
    if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0)
        die ("Failed to register mixer element");

    ret = snd_mixer_load(alsa_mix_handle);
    if (ret < 0)
        die ("Failed to load mixer element");
    alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
    if (!alsa_mix_elem)
        die ("Failed to find mixer element");
    snd_mixer_selem_get_playback_volume_range (alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv);
    alsa_mix_range = alsa_mix_maxv - alsa_mix_minv;

    return 0;
}
Пример #27
0
void toggleMute(struct playerHandles *ph, int *mute){
	long val;
	int err;
	float range_p;
	long current=*mute;
	long vmin,vmax;
	char tail[OUTPUT_TAIL_SIZE];
	snd_mixer_t *handle;
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid;

	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid,0);
	snd_mixer_selem_id_set_name(sid,"PCM");

	if(snd_mixer_open(&handle,0)<0)
		return;

	if(snd_mixer_attach(handle,"default")<0){
		snd_mixer_close(handle);
		return;
	}

	if(snd_mixer_selem_register(handle,NULL,NULL)<0){
		snd_mixer_close(handle);
		return;
	}

	if(snd_mixer_load(handle)<0){
		snd_mixer_close(handle);
		return;
	}

	elem=snd_mixer_find_selem(handle,sid);
	if(!elem){
		snd_mixer_close(handle);
		return;
	}

	snd_mixer_selem_get_playback_volume_range(elem,&vmin,&vmax);
	range_p = (100.0f/(float)(vmax-vmin));
	if(*mute>0){ // Unmute and perform volume change
		*mute=0;
		sprintf(tail,"Volume: %ld%%",current);
		addStatusTail(tail,ph->outdetail);
		current=current/range_p+vmin;
	}
	else{ // Mute
		snd_mixer_selem_get_playback_volume(elem,0,&current);
		*mute=current*range_p+vmin;
		current=0;
		addStatusTail("Volume Muted",ph->outdetail);
	}
	fflush(stdout);

	if(snd_mixer_selem_set_playback_volume(elem,0,current)<0){
		snd_mixer_close(handle);
		return;
	}
	if(snd_mixer_selem_set_playback_volume(elem,1,current)<0){
		snd_mixer_close(handle);
		return;
	}

	snd_mixer_close(handle);
}
Пример #28
0
void changeVolume(struct playerHandles *ph, int mod){
	long val;
	int err;
	float range_p;
	long cur_vol,new_volume;
	long vmin,vmax;
	char tail[OUTPUT_TAIL_SIZE];
	snd_mixer_t *handle;
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid;

	snd_mixer_selem_id_alloca(&sid);
	snd_mixer_selem_id_set_index(sid,0);
	snd_mixer_selem_id_set_name(sid,"PCM");

	if(snd_mixer_open(&handle,0)<0)
		return;

	if(snd_mixer_attach(handle,"default")<0){
		snd_mixer_close(handle);
		return;
	}

	if(snd_mixer_selem_register(handle,NULL,NULL)<0){
		snd_mixer_close(handle);
		return;
	}

	if(snd_mixer_load(handle)<0){
		snd_mixer_close(handle);
		return;
	}

	elem=snd_mixer_find_selem(handle,sid);
	if(!elem){
		snd_mixer_close(handle);
		return;
	}

	snd_mixer_selem_get_playback_volume_range(elem,&vmin,&vmax);
	range_p = (100.0f/(float)(vmax-vmin));

	snd_mixer_selem_get_playback_volume(elem,0,&cur_vol);
	new_volume = cur_vol+vmin+mod/range_p;
	if(new_volume==cur_vol && mod!=0)new_volume+=(mod<0?-1:1);
	if(new_volume<vmin)new_volume=vmin;
	if(new_volume>vmax)new_volume=vmax;
	if(snd_mixer_selem_set_playback_volume(elem,0,new_volume)<0){
		snd_mixer_close(handle);
		return;
	}

	sprintf(tail,"Volume: %d%%",(int)((float)range_p*(float)new_volume));
	addStatusTail(tail,ph->outdetail);

	snd_mixer_selem_get_playback_volume(elem,1,&cur_vol);
	new_volume = cur_vol+vmin+mod/range_p;
	if(new_volume==cur_vol && mod!=0)new_volume+=(mod<0?-1:1);
	if(new_volume<vmin)new_volume=vmin;
	if(new_volume>vmax)new_volume=vmax;
	if(snd_mixer_selem_set_playback_volume(elem,1,new_volume)<0){
		snd_mixer_close(handle);
		return;
	}

	snd_mixer_close(handle);
}
Пример #29
0
/* to set/get/query special features/parameters */
static int control(int cmd, void *arg)
{
  switch(cmd) {
  case AOCONTROL_QUERY_FORMAT:
    return CONTROL_TRUE;
  case AOCONTROL_GET_VOLUME:
  case AOCONTROL_SET_VOLUME:
    {
      ao_control_vol_t *vol = (ao_control_vol_t *)arg;

      int err;
      snd_mixer_t *handle;
      snd_mixer_elem_t *elem;
      snd_mixer_selem_id_t *sid;

      char *mix_name = "PCM";
      char *card = "default";
      int mix_index = 0;

      long pmin, pmax;
      long get_vol, set_vol;
      float f_multi;

      if(AF_FORMAT_IS_IEC61937(ao_data.format))
	return CONTROL_TRUE;

      if(mixer_channel) {
	 char *test_mix_index;

	 mix_name = strdup(mixer_channel);
	 if ((test_mix_index = strchr(mix_name, ','))){
		*test_mix_index = 0;
		test_mix_index++;
		mix_index = strtol(test_mix_index, &test_mix_index, 0);

		if (*test_mix_index){
		  mp_msg(MSGT_AO,MSGL_ERR,
		    MSGTR_AO_ALSA_InvalidMixerIndexDefaultingToZero);
		  mix_index = 0 ;
		}
	 }
      }
      if(mixer_device) card = mixer_device;

      //allocate simple id
      snd_mixer_selem_id_alloca(&sid);

      //sets simple-mixer index and name
      snd_mixer_selem_id_set_index(sid, mix_index);
      snd_mixer_selem_id_set_name(sid, mix_name);

      if (mixer_channel) {
	free(mix_name);
	mix_name = NULL;
      }

      if ((err = snd_mixer_open(&handle, 0)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerOpenError, snd_strerror(err));
	return CONTROL_ERROR;
      }

      if ((err = snd_mixer_attach(handle, card)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerAttachError,
	       card, snd_strerror(err));
	snd_mixer_close(handle);
	return CONTROL_ERROR;
      }

      if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerRegisterError, snd_strerror(err));
	snd_mixer_close(handle);
	return CONTROL_ERROR;
      }
      err = snd_mixer_load(handle);
      if (err < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_MixerLoadError, snd_strerror(err));
	snd_mixer_close(handle);
	return CONTROL_ERROR;
      }

      elem = snd_mixer_find_selem(handle, sid);
      if (!elem) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToFindSimpleControl,
	       snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
	snd_mixer_close(handle);
	return CONTROL_ERROR;
	}

      snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax);
      f_multi = (100 / (float)(pmax - pmin));

      if (cmd == AOCONTROL_SET_VOLUME) {

	set_vol = vol->left / f_multi + pmin + 0.5;

	//setting channels
	if ((err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, set_vol)) < 0) {
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSettingLeftChannel,
		 snd_strerror(err));
	  snd_mixer_close(handle);
	  return CONTROL_ERROR;
	}
	mp_msg(MSGT_AO,MSGL_DBG2,"left=%li, ", set_vol);

	set_vol = vol->right / f_multi + pmin + 0.5;

	if ((err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, set_vol)) < 0) {
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSettingRightChannel,
		 snd_strerror(err));
	  snd_mixer_close(handle);
	  return CONTROL_ERROR;
	}
	mp_msg(MSGT_AO,MSGL_DBG2,"right=%li, pmin=%li, pmax=%li, mult=%f\n",
	       set_vol, pmin, pmax, f_multi);

	if (snd_mixer_selem_has_playback_switch(elem)) {
	  int lmute = (vol->left == 0.0);
	  int rmute = (vol->right == 0.0);
	  if (snd_mixer_selem_has_playback_switch_joined(elem)) {
	    lmute = rmute = lmute && rmute;
	  } else {
	    snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, !rmute);
	  }
	  snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, !lmute);
	}
      }
      else {
	snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &get_vol);
	vol->left = (get_vol - pmin) * f_multi;
	snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &get_vol);
	vol->right = (get_vol - pmin) * f_multi;

	mp_msg(MSGT_AO,MSGL_DBG2,"left=%f, right=%f\n",vol->left,vol->right);
      }
      snd_mixer_close(handle);
      return CONTROL_OK;
    }

  } //end switch
  return CONTROL_UNKNOWN;
}
Пример #30
0
int indicator_music_init(Indicator *indicator) {
	DBusMessage* msg;
	DBusMessageIter args, element;
	DBusPendingCall* pending;
	char *player;
	int current_type;
	
	if(!dbus.session.connection)
		return -1;
	
	if(!(msg=dbus_message_new_method_call(dbus.interface, dbus.object, dbus.interface, "ListNames")))
		return -1;
	
	if(!dbus_connection_send_with_reply(dbus.session.connection, msg, &pending, -1)) {
		dbus_connection_unref(dbus.session.connection);
		return -1;
	}
	if(!pending) {
		dbus_message_unref(msg);
		dbus_connection_unref(dbus.session.connection);
		return -1;
	}
	dbus_connection_flush(dbus.session.connection);
	dbus_message_unref(msg);
	dbus_pending_call_block(pending);

	if(!(msg=dbus_pending_call_steal_reply(pending))) {
		dbus_connection_unref(dbus.session.connection);
		return -1;
	}
	dbus_pending_call_unref(pending);

	if(!(dbus_message_iter_init(msg, &args)&&dbus_message_iter_get_arg_type(&args)==DBUS_TYPE_ARRAY)) {
		dbus_message_unref(msg);
		dbus_connection_unref(dbus.session.connection);
		return -1;
	}
	
	for(dbus_message_iter_recurse(&args, &element); (current_type=dbus_message_iter_get_arg_type(&element))!=DBUS_TYPE_INVALID; dbus_message_iter_next(&element)) {
		if(current_type!=DBUS_TYPE_STRING)
			continue;
		dbus_message_iter_get_basic(&element, &player);
		if(!strncmp(player, mpris.base, strlen(mpris.base))) {
			mediaplayer_register(player+strlen(mpris.base));
		}
	}
	dbus_message_unref(msg);
	
	dbus_bus_add_match(dbus.session.connection, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", &dbus.session.error);
	dbus_connection_flush(dbus.session.connection);
	if(dbus_error_is_set(&dbus.session.error)) { 
		dbus_connection_unref(dbus.session.connection);
		mediaplayer_deregister_all();
		return -1;
	}
	
	/*init alsa*/
	snd_mixer_selem_id_alloca(&alsa.sid);
	snd_mixer_selem_id_set_index(alsa.sid, alsa.mix_index);
	snd_mixer_selem_id_set_name(alsa.sid, alsa.mix_name);
	
	if((snd_mixer_open(&alsa.handle, 0))<0)
		return -1;
	if((snd_mixer_attach(alsa.handle, alsa.card))<0) {
		snd_mixer_close(alsa.handle);
		return -1;
	}
	if((snd_mixer_selem_register(alsa.handle, NULL, NULL))<0) {
		snd_mixer_close(alsa.handle);
		return -1;
	}
	if(snd_mixer_load(alsa.handle)<0) {
		snd_mixer_close(alsa.handle);
		return -1;
	}
	if(!(alsa.elem=snd_mixer_find_selem(alsa.handle, alsa.sid))) {
		snd_mixer_close(alsa.handle);
		return -1;
	}
	
	snd_mixer_selem_get_playback_volume_range (alsa.elem, &alsa.minv, &alsa.maxv);
	return 0;
}