1062e67a26e0553dd142be622821f493df541f0c6Phil Burk/*
2062e67a26e0553dd142be622821f493df541f0c6Phil Burk**
3062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Copyright 2015, The Android Open Source Project
4062e67a26e0553dd142be622821f493df541f0c6Phil Burk**
5062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Licensed under the Apache License, Version 2.0 (the "License");
6062e67a26e0553dd142be622821f493df541f0c6Phil Burk** you may not use this file except in compliance with the License.
7062e67a26e0553dd142be622821f493df541f0c6Phil Burk** You may obtain a copy of the License at
8062e67a26e0553dd142be622821f493df541f0c6Phil Burk**
9062e67a26e0553dd142be622821f493df541f0c6Phil Burk**     http://www.apache.org/licenses/LICENSE-2.0
10062e67a26e0553dd142be622821f493df541f0c6Phil Burk**
11062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Unless required by applicable law or agreed to in writing, software
12062e67a26e0553dd142be622821f493df541f0c6Phil Burk** distributed under the License is distributed on an "AS IS" BASIS,
13062e67a26e0553dd142be622821f493df541f0c6Phil Burk** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14062e67a26e0553dd142be622821f493df541f0c6Phil Burk** See the License for the specific language governing permissions and
15062e67a26e0553dd142be622821f493df541f0c6Phil Burk** limitations under the License.
16062e67a26e0553dd142be622821f493df541f0c6Phil Burk*/
17062e67a26e0553dd142be622821f493df541f0c6Phil Burk
18062e67a26e0553dd142be622821f493df541f0c6Phil Burk#define LOG_TAG "AudioFlinger"
19062e67a26e0553dd142be622821f493df541f0c6Phil Burk//#define LOG_NDEBUG 0
20062e67a26e0553dd142be622821f493df541f0c6Phil Burk
21062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include <hardware/audio.h>
22062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include <utils/Log.h>
23062e67a26e0553dd142be622821f493df541f0c6Phil Burk
24062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include "AudioHwDevice.h"
25062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include "AudioStreamOut.h"
26062e67a26e0553dd142be622821f493df541f0c6Phil Burk
27062e67a26e0553dd142be622821f493df541f0c6Phil Burknamespace android {
28062e67a26e0553dd142be622821f493df541f0c6Phil Burk
29062e67a26e0553dd142be622821f493df541f0c6Phil Burk// ----------------------------------------------------------------------------
30062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags)
31062e67a26e0553dd142be622821f493df541f0c6Phil Burk        : audioHwDev(dev)
32062e67a26e0553dd142be622821f493df541f0c6Phil Burk        , stream(NULL)
33062e67a26e0553dd142be622821f493df541f0c6Phil Burk        , flags(flags)
3490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        , mFramesWritten(0)
3590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        , mFramesWrittenAtStandby(0)
3690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        , mRenderPosition(0)
3790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        , mRateMultiplier(1)
38fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        , mHalFormatHasProportionalFrames(false)
3990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        , mHalFrameSize(0)
40062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
41062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
42062e67a26e0553dd142be622821f493df541f0c6Phil Burk
4390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burkaudio_hw_device_t *AudioStreamOut::hwDev() const
44062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
45062e67a26e0553dd142be622821f493df541f0c6Phil Burk    return audioHwDev->hwDevice();
46062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
47062e67a26e0553dd142be622821f493df541f0c6Phil Burk
4890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burkstatus_t AudioStreamOut::getRenderPosition(uint64_t *frames)
49062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
50062e67a26e0553dd142be622821f493df541f0c6Phil Burk    if (stream == NULL) {
51062e67a26e0553dd142be622821f493df541f0c6Phil Burk        return NO_INIT;
52062e67a26e0553dd142be622821f493df541f0c6Phil Burk    }
5390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
5490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    uint32_t halPosition = 0;
5590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    status_t status = stream->get_render_position(stream, &halPosition);
5690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    if (status != NO_ERROR) {
5790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        return status;
5890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
5990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
6090eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // Maintain a 64-bit render position using the 32-bit result from the HAL.
6190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // This delta calculation relies on the arithmetic overflow behavior
6290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // of integers. For example (100 - 0xFFFFFFF0) = 116.
6390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    uint32_t truncatedPosition = (uint32_t)mRenderPosition;
6490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    int32_t deltaHalPosition = (int32_t)(halPosition - truncatedPosition);
6590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    if (deltaHalPosition > 0) {
6690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        mRenderPosition += deltaHalPosition;
6790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
6890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // Scale from HAL sample rate to application rate.
6990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    *frames = mRenderPosition / mRateMultiplier;
7090eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
7190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    return status;
7290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk}
7390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
7490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk// return bottom 32-bits of the render position
7590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burkstatus_t AudioStreamOut::getRenderPosition(uint32_t *frames)
7690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk{
7790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    uint64_t position64 = 0;
7890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    status_t status = getRenderPosition(&position64);
7990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    if (status == NO_ERROR) {
8090eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        *frames = (uint32_t)position64;
8190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
8290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    return status;
83062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
84062e67a26e0553dd142be622821f493df541f0c6Phil Burk
85062e67a26e0553dd142be622821f493df541f0c6Phil Burkstatus_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timespec *timestamp)
86062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
87062e67a26e0553dd142be622821f493df541f0c6Phil Burk    if (stream == NULL) {
88062e67a26e0553dd142be622821f493df541f0c6Phil Burk        return NO_INIT;
89062e67a26e0553dd142be622821f493df541f0c6Phil Burk    }
9090eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
9190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    uint64_t halPosition = 0;
9290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    status_t status = stream->get_presentation_position(stream, &halPosition, timestamp);
9390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    if (status != NO_ERROR) {
9490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        return status;
9590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
9690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
9790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // Adjust for standby using HAL rate frames.
9890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    // Only apply this correction if the HAL is getting PCM frames.
99fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    if (mHalFormatHasProportionalFrames) {
10090eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ?
10190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk                0 : (halPosition - mFramesWrittenAtStandby);
10290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        // Scale from HAL sample rate to application rate.
10390eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        *frames = adjustedPosition / mRateMultiplier;
10490eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    } else {
10590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        // For offloaded MP3 and other compressed formats.
10690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        *frames = halPosition;
10790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
10890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk
10990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    return status;
110062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
111062e67a26e0553dd142be622821f493df541f0c6Phil Burk
112062e67a26e0553dd142be622821f493df541f0c6Phil Burkstatus_t AudioStreamOut::open(
113062e67a26e0553dd142be622821f493df541f0c6Phil Burk        audio_io_handle_t handle,
114062e67a26e0553dd142be622821f493df541f0c6Phil Burk        audio_devices_t devices,
115062e67a26e0553dd142be622821f493df541f0c6Phil Burk        struct audio_config *config,
116062e67a26e0553dd142be622821f493df541f0c6Phil Burk        const char *address)
117062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
11890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    audio_stream_out_t *outStream;
119fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk
120fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
121fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                ? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
122fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                : flags;
123fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk
124062e67a26e0553dd142be622821f493df541f0c6Phil Burk    int status = hwDev()->open_output_stream(
125062e67a26e0553dd142be622821f493df541f0c6Phil Burk            hwDev(),
126062e67a26e0553dd142be622821f493df541f0c6Phil Burk            handle,
127062e67a26e0553dd142be622821f493df541f0c6Phil Burk            devices,
128fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk            customFlags,
129062e67a26e0553dd142be622821f493df541f0c6Phil Burk            config,
130062e67a26e0553dd142be622821f493df541f0c6Phil Burk            &outStream,
131062e67a26e0553dd142be622821f493df541f0c6Phil Burk            address);
132fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    ALOGV("AudioStreamOut::open(), HAL returned "
133fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk            " stream %p, sampleRate %d, Format %#x, "
134062e67a26e0553dd142be622821f493df541f0c6Phil Burk            "channelMask %#x, status %d",
135062e67a26e0553dd142be622821f493df541f0c6Phil Burk            outStream,
136062e67a26e0553dd142be622821f493df541f0c6Phil Burk            config->sample_rate,
137062e67a26e0553dd142be622821f493df541f0c6Phil Burk            config->format,
138062e67a26e0553dd142be622821f493df541f0c6Phil Burk            config->channel_mask,
139062e67a26e0553dd142be622821f493df541f0c6Phil Burk            status);
140062e67a26e0553dd142be622821f493df541f0c6Phil Burk
141fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    // Some HALs may not recognize AUDIO_FORMAT_IEC61937. But if we declare
142fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    // it as PCM then it will probably work.
143fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    if (status != NO_ERROR && config->format == AUDIO_FORMAT_IEC61937) {
144fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        struct audio_config customConfig = *config;
145fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        customConfig.format = AUDIO_FORMAT_PCM_16_BIT;
146fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk
147fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        status = hwDev()->open_output_stream(
148fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                hwDev(),
149fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                handle,
150fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                devices,
151fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                customFlags,
152fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                &customConfig,
153fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                &outStream,
154fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk                address);
155fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        ALOGV("AudioStreamOut::open(), treat IEC61937 as PCM, status = %d", status);
156fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk    }
157fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk
158062e67a26e0553dd142be622821f493df541f0c6Phil Burk    if (status == NO_ERROR) {
159062e67a26e0553dd142be622821f493df541f0c6Phil Burk        stream = outStream;
160fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        mHalFormatHasProportionalFrames = audio_has_proportional_frames(config->format);
16190eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        mHalFrameSize = audio_stream_out_frame_size(stream);
162062e67a26e0553dd142be622821f493df541f0c6Phil Burk    }
163062e67a26e0553dd142be622821f493df541f0c6Phil Burk
164062e67a26e0553dd142be622821f493df541f0c6Phil Burk    return status;
165062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
166062e67a26e0553dd142be622821f493df541f0c6Phil Burk
167ca5e6143740299c877d69e97f7968cd04476d32cPhil Burkaudio_format_t AudioStreamOut::getFormat() const
168062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
169ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk    return stream->common.get_format(&stream->common);
170ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk}
171ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk
172ca5e6143740299c877d69e97f7968cd04476d32cPhil Burkuint32_t AudioStreamOut::getSampleRate() const
173ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk{
174ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk    return stream->common.get_sample_rate(&stream->common);
175ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk}
176ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk
177ca5e6143740299c877d69e97f7968cd04476d32cPhil Burkaudio_channel_mask_t AudioStreamOut::getChannelMask() const
178ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk{
179ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk    return stream->common.get_channels(&stream->common);
180062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
181062e67a26e0553dd142be622821f493df541f0c6Phil Burk
182062e67a26e0553dd142be622821f493df541f0c6Phil Burkint AudioStreamOut::flush()
183062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
184062e67a26e0553dd142be622821f493df541f0c6Phil Burk    ALOG_ASSERT(stream != NULL);
18590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    mRenderPosition = 0;
18690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    mFramesWritten = 0;
18790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    mFramesWrittenAtStandby = 0;
188062e67a26e0553dd142be622821f493df541f0c6Phil Burk    if (stream->flush != NULL) {
189062e67a26e0553dd142be622821f493df541f0c6Phil Burk        return stream->flush(stream);
190062e67a26e0553dd142be622821f493df541f0c6Phil Burk    }
191062e67a26e0553dd142be622821f493df541f0c6Phil Burk    return NO_ERROR;
192062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
193062e67a26e0553dd142be622821f493df541f0c6Phil Burk
194062e67a26e0553dd142be622821f493df541f0c6Phil Burkint AudioStreamOut::standby()
195062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
196062e67a26e0553dd142be622821f493df541f0c6Phil Burk    ALOG_ASSERT(stream != NULL);
19790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    mRenderPosition = 0;
19890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    mFramesWrittenAtStandby = mFramesWritten;
199062e67a26e0553dd142be622821f493df541f0c6Phil Burk    return stream->common.standby(&stream->common);
200062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
201062e67a26e0553dd142be622821f493df541f0c6Phil Burk
20290eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burkssize_t AudioStreamOut::write(const void *buffer, size_t numBytes)
203062e67a26e0553dd142be622821f493df541f0c6Phil Burk{
204062e67a26e0553dd142be622821f493df541f0c6Phil Burk    ALOG_ASSERT(stream != NULL);
20590eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    ssize_t bytesWritten = stream->write(stream, buffer, numBytes);
20690eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    if (bytesWritten > 0 && mHalFrameSize > 0) {
20790eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk        mFramesWritten += bytesWritten / mHalFrameSize;
20890eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    }
20990eea7631b07117e46ae8b84889a2baa3eee7aeaPhil Burk    return bytesWritten;
210062e67a26e0553dd142be622821f493df541f0c6Phil Burk}
211062e67a26e0553dd142be622821f493df541f0c6Phil Burk
212062e67a26e0553dd142be622821f493df541f0c6Phil Burk} // namespace android
213