Exemple #1
0
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)
{
    /* XXX: fake timing for audio output */
    usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
           out_get_sample_rate(&stream->common));
    return bytes;
}
Exemple #3
0
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;
}
Exemple #5
0
static int adev_open_output_stream(struct audio_hw_device *dev,
                                   audio_io_handle_t handle,
                                   audio_devices_t devices,
                                   audio_output_flags_t flags,
                                   struct audio_config *config,
                                   struct audio_stream_out **stream_out)
{
    struct audio_device *adev = (struct audio_device *)dev;
    struct stream_out *out;
    int ret;

    out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
    if (!out)
        return -ENOMEM;

    out->stream.common.get_sample_rate = out_get_sample_rate;
    out->stream.common.set_sample_rate = out_set_sample_rate;
    out->stream.common.get_buffer_size = out_get_buffer_size;
    out->stream.common.get_channels = out_get_channels;
    out->stream.common.get_format = out_get_format;
    out->stream.common.set_format = out_set_format;
    out->stream.common.standby = out_standby;
    out->stream.common.dump = out_dump;
    out->stream.common.set_parameters = out_set_parameters;
    out->stream.common.get_parameters = out_get_parameters;
    out->stream.common.add_audio_effect = out_add_audio_effect;
    out->stream.common.remove_audio_effect = out_remove_audio_effect;
    out->stream.get_latency = out_get_latency;
    out->stream.set_volume = out_set_volume;
    out->stream.write = out_write;
    out->stream.get_render_position = out_get_render_position;
    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;

    out->dev = adev;

    config->format = out_get_format(&out->stream.common);
    config->channel_mask = out_get_channels(&out->stream.common);
    config->sample_rate = out_get_sample_rate(&out->stream.common);

    out->standby = true;

    adev->card = -1;
    adev->device = -1;

    *stream_out = &out->stream;
    return 0;

err_open:
    free(out);
    *stream_out = NULL;
    return ret;
}
Exemple #6
0
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
    return (pcm_config.period_size * pcm_config.period_count * 1000) /
           out_get_sample_rate(&stream->common);
}
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
                         size_t bytes)
{
    //ALOGV("out_write(bytes=%d)", bytes);
    ssize_t written_frames = 0;
    struct submix_stream_out *out = reinterpret_cast<struct submix_stream_out *>(stream);

    const size_t frame_size = audio_stream_frame_size(&stream->common);
    const size_t frames = bytes / frame_size;

    pthread_mutex_lock(&out->dev->lock);

    out->dev->output_standby = false;

    sp<MonoPipe> sink = out->dev->rsxSink.get();
    if (sink != 0) {
        if (sink->isShutdown()) {
            sink.clear();
            pthread_mutex_unlock(&out->dev->lock);
            // the pipe has already been shutdown, this buffer will be lost but we must
            //   simulate timing so we don't drain the output faster than realtime
            usleep(frames * 1000000 / out_get_sample_rate(&stream->common));
            return bytes;
        }
    } else {
        pthread_mutex_unlock(&out->dev->lock);
        ALOGE("out_write without a pipe!");
        ALOG_ASSERT("out_write without a pipe!");
        return 0;
    }

    pthread_mutex_unlock(&out->dev->lock);

    written_frames = sink->write(buffer, frames);

    if (written_frames < 0) {
        if (written_frames == (ssize_t)NEGOTIATE) {
            ALOGE("out_write() write to pipe returned NEGOTIATE");

            pthread_mutex_lock(&out->dev->lock);
            sink.clear();
            pthread_mutex_unlock(&out->dev->lock);

            written_frames = 0;
            return 0;
        } else {
            // write() returned UNDERRUN or WOULD_BLOCK, retry
            ALOGE("out_write() write to pipe returned unexpected %16lx", written_frames);
            written_frames = sink->write(buffer, frames);
        }
    }

    pthread_mutex_lock(&out->dev->lock);
    sink.clear();
    pthread_mutex_unlock(&out->dev->lock);

    if (written_frames < 0) {
        ALOGE("out_write() failed writing to pipe with %16lx", written_frames);
        return 0;
    } else {
        ALOGV("out_write() wrote %lu bytes)", written_frames * frame_size);
        return written_frames * frame_size;
    }
}
static int adev_open_output_stream(struct audio_hw_device *dev,
                                   audio_io_handle_t handle,
                                   audio_devices_t devices,
                                   audio_output_flags_t flags,
                                   struct audio_config *config,
                                   struct audio_stream_out **stream_out)
{
    struct audio_device *adev = (struct audio_device *)dev;
    struct stream_out *out;
    int ret;
    ALOGV("%s enter card %d device %d ",__func__, adev->card, adev->device);

    out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
    if (!out)
        return -ENOMEM;

    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;

    if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
        ALOGV("%s: USB Audio (device mode) HD",__func__);
        if (config->format == 0)
            config->format = pcm_config_HD_default.format;
        if (config->channel_mask == 0)
            config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
        if (config->sample_rate == 0)
            config->sample_rate = pcm_config_HD_default.rate;
        out->pcm_config.period_size        = pcm_config_HD_default.period_size;
        out->flags |= flags;
    } else {
        ALOGV("%s: USB Audio (device mode) Stereo",__func__);
        if (config->format == 0)
            config->format = pcm_config_default.format;
        if (config->channel_mask == 0)
            config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
        if (config->sample_rate == 0)
            config->sample_rate = pcm_config_default.rate;

        out->pcm_config.period_size        = pcm_config_default.period_size;
    }

    out->channel_mask                      = config->channel_mask;

    out->pcm_config.channels               = popcount(config->channel_mask);
    out->pcm_config.rate                   = config->sample_rate;
    out->pcm_config.format                 = config->format;
    out->pcm_config.period_count           = pcm_config_default.period_count;

    out->stream.common.get_sample_rate     = out_get_sample_rate;
    out->stream.common.set_sample_rate     = out_set_sample_rate;
    out->stream.common.get_buffer_size     = out_get_buffer_size;
    out->stream.common.get_channels        = out_get_channels;
    out->stream.common.get_format          = out_get_format;
    out->stream.common.set_format          = out_set_format;
    out->stream.common.standby             = out_standby;
    out->stream.common.dump                = out_dump;
    out->stream.common.set_parameters      = out_set_parameters;
    out->stream.common.get_parameters      = out_get_parameters;
    out->stream.common.add_audio_effect    = out_add_audio_effect;
    out->stream.common.remove_audio_effect = out_remove_audio_effect;
    out->stream.get_latency                = out_get_latency;
    out->stream.set_volume                 = out_set_volume;
    out->stream.write                      = out_write;
    out->stream.get_render_position        = out_get_render_position;
    out->stream.get_next_write_timestamp   = out_get_next_write_timestamp;

    out->dev                               = adev;
    config->format                         = out_get_format(&out->stream.common);
    config->channel_mask                   = out_get_channels(&out->stream.common);
    config->sample_rate                    = out_get_sample_rate(&out->stream.common);

    out->standby = true;
    adev->card = -1;
    adev->device = -1;

    *stream_out = &out->stream;
    ALOGV("%s exit",__func__);
    return 0;
}