static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { int ret; struct stream_out *out = (struct stream_out *)stream; pthread_mutex_lock(&out->dev->lock); pthread_mutex_lock(&out->lock); if (out->standby) { ret = start_output_stream(out); if (ret != 0) { goto err; } out->standby = false; } pcm_write(out->pcm, (void *)buffer, bytes); pthread_mutex_unlock(&out->lock); pthread_mutex_unlock(&out->dev->lock); return bytes; err: pthread_mutex_unlock(&out->lock); if (ret != 0) { usleep(bytes * 1000000 / audio_stream_frame_size(&stream->common) / out_get_sample_rate(&stream->common)); } return bytes; }
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { int ret; struct stream_out *out = (struct stream_out *)stream; pthread_mutex_lock(&out->dev->lock); pthread_mutex_lock(&out->lock); if (out->standby) { ret = start_output_stream(out); if (ret != 0) { pthread_mutex_unlock(&out->dev->lock); goto err; } out->standby = false; } pthread_mutex_unlock(&out->dev->lock); alsa_device_proxy* proxy = &out->proxy; const void * write_buff = buffer; int num_write_buff_bytes = bytes; const int num_device_channels = proxy_get_channel_count(proxy); /* what we told alsa */ const int num_req_channels = out->hal_channel_count; /* what we told AudioFlinger */ if (num_device_channels != num_req_channels) { /* allocate buffer */ const size_t required_conversion_buffer_size = bytes * num_device_channels / num_req_channels; if (required_conversion_buffer_size > out->conversion_buffer_size) { out->conversion_buffer_size = required_conversion_buffer_size; out->conversion_buffer = realloc(out->conversion_buffer, out->conversion_buffer_size); } /* convert data */ const audio_format_t audio_format = out_get_format(&(out->stream.common)); const unsigned sample_size_in_bytes = audio_bytes_per_sample(audio_format); num_write_buff_bytes = adjust_channels(write_buff, num_req_channels, out->conversion_buffer, num_device_channels, sample_size_in_bytes, num_write_buff_bytes); write_buff = out->conversion_buffer; } if (write_buff != NULL && num_write_buff_bytes != 0) { proxy_write(&out->proxy, write_buff, num_write_buff_bytes); } pthread_mutex_unlock(&out->lock); return bytes; err: pthread_mutex_unlock(&out->lock); if (ret != 0) { usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) / out_get_sample_rate(&stream->common)); } return bytes; }
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { int ret = 0; struct stream_out *out = (struct stream_out *)stream; struct audio_device *adev = out ? out->dev : NULL; if(adev == NULL) return -ENOSYS; ALOGV("%s enter",__func__); pthread_mutex_lock(&out->dev->lock); pthread_mutex_lock(&out->lock); // there is a possibility that the HD interface is open // and normal pcm stream is still active. Feed the new // interface to normal pcm stream if(adev->active_pcm) { if(adev->active_pcm != out->pcm) out->pcm = adev->active_pcm; } if ((out->standby) || (!adev->active_pcm)) { ret = start_output_stream(out); if (ret != 0) { goto err; } out->standby = false; } if(!out->pcm){ ALOGD("%s: null handle to write - device already closed",__func__); goto err; } ret = pcm_write(out->pcm, (void *)buffer, bytes); ALOGVV("%s: pcm_write returned = %d rate = %d",__func__,ret,out->pcm_config.rate); err: pthread_mutex_unlock(&out->lock); pthread_mutex_unlock(&out->dev->lock); if (ret != 0) { uint64_t duration_ms = ((bytes * 1000)/ (audio_stream_frame_size(&stream->common)) / (out_get_sample_rate(&stream->common))); ALOGV("%s : silence written", __func__); usleep(duration_ms * 1000); } ALOGV("%s exit",__func__); return bytes; }