/** * @brief Callback function called when the information on the * context's sink is retrieved. * @param ctx Context which operation has succeeded * @param info Structure containing the sink's information * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. * * This function saves the volume field of the passed structure to the * @c cvolume variable of the output instance and send an update volume * event to the frontend. */ static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info *info, int is_last, void *userdata) { pulse_driver_t *const this = (pulse_driver_t *) userdata; if (is_last < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", pa_strerror(pa_context_errno(this->context))); return; } if (!info) return; this->cvolume = info->volume; this->swvolume = pa_cvolume_avg(&info->volume); #if PA_PROTOCOL_VERSION >= 11 /* PulseAudio 0.9.7 and newer */ this->muted = info->mute; #else this->muted = pa_cvolume_is_muted (&this->cvolume); #endif /* send update volume event to frontend */ xine_event_t event; xine_audio_level_data_t data; xine_stream_t *stream; xine_list_iterator_t ite; data.right = data.left = (int) (pa_sw_volume_to_linear(this->swvolume)*100); data.mute = this->muted; event.type = XINE_EVENT_AUDIO_LEVEL; event.data = &data; event.data_length = sizeof(data); pthread_mutex_lock(&this->xine->streams_lock); for(ite = xine_list_front(this->xine->streams); ite; ite = xine_list_next(this->xine->streams, ite)) { stream = xine_list_get_value(this->xine->streams, ite); event.stream = stream; xine_event_send(stream, &event); } pthread_mutex_unlock(&this->xine->streams_lock); }
/* Each line sent is '\n' terminated */ if((buf[strlen(buf)] == '\0') && (buf[strlen(buf) - 1] != '\n')) strcat(buf, "\n"); return sock_data_write(xine, socket, buf, strlen(buf)); } /* * this is the most important broadcaster function. * it sends data to every connected client (slaves). */ static void broadcaster_data_write(broadcaster_t *this, const void *buf, int len) { xine_list_iterator_t ite; ite = xine_list_front (this->connections); while (ite) { int *psock = xine_list_get_value(this->connections, ite); ite = xine_list_next(this->connections, ite); /* in case of failure remove from list */ if( sock_data_write(this->stream->xine, *psock, buf, len) < 0 ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: closing socket %d\n", *psock); close(*psock); free(psock); xine_list_remove (this->connections, xine_list_prev(this->connections, ite)); }