Home | History | Annotate | Download | only in audioflinger
      1 /*
      2 **
      3 ** Copyright 2007, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #define LOG_TAG "AudioHwDevice"
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <system/audio.h>
     22 #include <utils/Log.h>
     23 
     24 #include <audio_utils/spdif/SPDIFEncoder.h>
     25 
     26 #include "AudioHwDevice.h"
     27 #include "AudioStreamOut.h"
     28 #include "SpdifStreamOut.h"
     29 
     30 namespace android {
     31 
     32 // ----------------------------------------------------------------------------
     33 
     34 status_t AudioHwDevice::openOutputStream(
     35         AudioStreamOut **ppStreamOut,
     36         audio_io_handle_t handle,
     37         audio_devices_t devices,
     38         audio_output_flags_t flags,
     39         struct audio_config *config,
     40         const char *address)
     41 {
     42 
     43     struct audio_config originalConfig = *config;
     44     AudioStreamOut *outputStream = new AudioStreamOut(this, flags);
     45 
     46     // Try to open the HAL first using the current format.
     47     ALOGV("openOutputStream(), try "
     48             " sampleRate %d, Format %#x, "
     49             "channelMask %#x",
     50             config->sample_rate,
     51             config->format,
     52             config->channel_mask);
     53     status_t status = outputStream->open(handle, devices, config, address);
     54 
     55     if (status != NO_ERROR) {
     56         delete outputStream;
     57         outputStream = NULL;
     58 
     59         // FIXME Look at any modification to the config.
     60         // The HAL might modify the config to suggest a wrapped format.
     61         // Log this so we can see what the HALs are doing.
     62         ALOGI("openOutputStream(), HAL returned"
     63             " sampleRate %d, Format %#x, "
     64             "channelMask %#x, status %d",
     65             config->sample_rate,
     66             config->format,
     67             config->channel_mask,
     68             status);
     69 
     70         // If the data is encoded then try again using wrapped PCM.
     71         bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
     72                 && ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
     73                 && ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);
     74 
     75         if (wrapperNeeded) {
     76             if (SPDIFEncoder::isFormatSupported(originalConfig.format)) {
     77                 outputStream = new SpdifStreamOut(this, flags, originalConfig.format);
     78                 status = outputStream->open(handle, devices, &originalConfig, address);
     79                 if (status != NO_ERROR) {
     80                     ALOGE("ERROR - openOutputStream(), SPDIF open returned %d",
     81                         status);
     82                     delete outputStream;
     83                     outputStream = NULL;
     84                 }
     85             } else {
     86                 ALOGE("ERROR - openOutputStream(), SPDIFEncoder does not support format 0x%08x",
     87                     originalConfig.format);
     88             }
     89         }
     90     }
     91 
     92     *ppStreamOut = outputStream;
     93     return status;
     94 }
     95 
     96 bool AudioHwDevice::supportsAudioPatches() const {
     97     bool result;
     98     return mHwDevice->supportsAudioPatches(&result) == OK ? result : false;
     99 }
    100 
    101 
    102 }; // namespace android
    103