blob: c29fc89468f91b63b765640cbcea7e64097f920e [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/lib/media/audio_output_manager.h"
#include <cstring>
#include <string>
#include "garnet/lib/media/audio_output_device.h"
#include "garnet/lib/media/audio_output_stream.h"
#include "garnet/lib/media/hw_stub.h"
#include "lib/fxl/logging.h"
namespace media_client {
AudioOutputManager::AudioOutputManager() {
num_devices_ = kStubNumDevices;
EnumerateDevices();
}
AudioOutputManager::~AudioOutputManager() {}
void AudioOutputManager::EnumerateDevices() {
for (int device_num = 0; device_num < num_devices_; ++device_num) {
std::unique_ptr<AudioOutputDevice> device =
std::make_unique<AudioOutputDevice>(
kStubDevId, kStubDevName, kStubPreferredRate,
kStubPreferredNumChans, kStubPreferredBufferSize);
devices_.push_back(std::move(device));
}
}
int AudioOutputManager::GetOutputDevices(
fuchsia_audio_device_description* buffer,
int num_device_descriptions) {
FXL_DCHECK((buffer == nullptr) == (num_device_descriptions == 0));
FXL_DCHECK(num_device_descriptions >= 0);
if (!buffer) {
return num_devices_;
}
int dev_num, num_to_copy = std::min(num_device_descriptions, num_devices_);
for (dev_num = 0; dev_num < num_to_copy; ++dev_num) {
std::strcpy(buffer[dev_num].id, devices_[dev_num]->id().c_str());
std::strcpy(buffer[dev_num].name, devices_[dev_num]->name().c_str());
}
return num_to_copy;
}
// Returns -1 if there is no device with the given ID.
int AudioOutputManager::GetDeviceNumFromId(char* device_id) {
// Use |device_id| if present, else use the default device (0)
if (!device_id || !strlen(device_id)) {
return (num_devices_ ? 0 : -1);
}
for (int dev_num = 0; dev_num < num_devices_; ++dev_num) {
if (strcmp(devices_[dev_num]->id().c_str(), device_id) == 0) {
return dev_num;
}
}
return -1;
}
int AudioOutputManager::GetOutputDeviceDefaultParameters(
char* device_id,
fuchsia_audio_parameters* stream_params) {
FXL_DCHECK(stream_params);
int device_num = GetDeviceNumFromId(device_id);
if (device_num == -1) {
return ZX_ERR_NOT_FOUND; // Device was removed after a previous call to
} // fuchsia_audio_manager_get_output_devices_
stream_params->sample_rate = devices_[device_num]->preferred_sample_rate();
stream_params->num_channels = devices_[device_num]->preferred_num_channels();
stream_params->buffer_size = devices_[device_num]->preferred_buffer_size();
return ZX_OK;
}
int AudioOutputManager::CreateOutputStream(
char* device_id,
fuchsia_audio_parameters* stream_params,
media_client::AudioOutputStream** stream_out) {
FXL_DCHECK(stream_params);
int device_num = GetDeviceNumFromId(device_id);
if (device_num == -1) {
return ZX_ERR_NOT_FOUND; // Device was removed after a previous call to
} // fuchsia_audio_manager_get_output_devices_
media_client::AudioOutputStream* stream =
devices_[device_num]->CreateStream(stream_params);
if (!stream)
return ZX_ERR_CONNECTION_ABORTED;
*stream_out = stream;
return ZX_OK;
}
} // namespace media_client