output/oss: use class FileDescriptor
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
#include "OssOutputPlugin.hxx"
|
#include "OssOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
#include "mixer/MixerList.hxx"
|
#include "mixer/MixerList.hxx"
|
||||||
#include "system/fd_util.h"
|
#include "system/UniqueFileDescriptor.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@@ -64,7 +64,7 @@ class OssOutput final : AudioOutput {
|
|||||||
Manual<PcmExport> pcm_export;
|
Manual<PcmExport> pcm_export;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int fd;
|
FileDescriptor fd = FileDescriptor::Undefined();
|
||||||
const char *device;
|
const char *device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,7 +88,7 @@ class OssOutput final : AudioOutput {
|
|||||||
public:
|
public:
|
||||||
explicit OssOutput(const char *_device=nullptr)
|
explicit OssOutput(const char *_device=nullptr)
|
||||||
:AudioOutput(oss_flags),
|
:AudioOutput(oss_flags),
|
||||||
fd(-1), device(_device) {}
|
device(_device) {}
|
||||||
|
|
||||||
static AudioOutput *Create(EventLoop &event_loop,
|
static AudioOutput *Create(EventLoop &event_loop,
|
||||||
const ConfigBlock &block);
|
const ConfigBlock &block);
|
||||||
@@ -169,15 +169,10 @@ static const char *const default_devices[] = { "/dev/sound/dsp", "/dev/dsp" };
|
|||||||
static bool
|
static bool
|
||||||
oss_output_test_default_device(void)
|
oss_output_test_default_device(void)
|
||||||
{
|
{
|
||||||
int fd, i;
|
for (int i = ARRAY_SIZE(default_devices); --i >= 0; ) {
|
||||||
|
UniqueFileDescriptor fd;
|
||||||
for (i = ARRAY_SIZE(default_devices); --i >= 0; ) {
|
if (fd.Open(default_devices[i], O_WRONLY, 0))
|
||||||
fd = open_cloexec(default_devices[i], O_WRONLY, 0);
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
close(fd);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
FormatErrno(oss_output_domain,
|
FormatErrno(oss_output_domain,
|
||||||
"Error opening OSS device \"%s\"",
|
"Error opening OSS device \"%s\"",
|
||||||
@@ -239,9 +234,8 @@ OssOutput::Create(EventLoop &, const ConfigBlock &block)
|
|||||||
void
|
void
|
||||||
OssOutput::DoClose()
|
OssOutput::DoClose()
|
||||||
{
|
{
|
||||||
if (fd >= 0)
|
if (fd.IsDefined())
|
||||||
close(fd);
|
fd.Close();
|
||||||
fd = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,14 +252,14 @@ enum oss_setup_result {
|
|||||||
* returned. Any other failure throws std::runtime_error.
|
* returned. Any other failure throws std::runtime_error.
|
||||||
*/
|
*/
|
||||||
static enum oss_setup_result
|
static enum oss_setup_result
|
||||||
oss_try_ioctl_r(int fd, unsigned long request, int *value_r,
|
oss_try_ioctl_r(FileDescriptor fd, unsigned long request, int *value_r,
|
||||||
const char *msg)
|
const char *msg)
|
||||||
{
|
{
|
||||||
assert(fd >= 0);
|
assert(fd.IsDefined());
|
||||||
assert(value_r != nullptr);
|
assert(value_r != nullptr);
|
||||||
assert(msg != nullptr);
|
assert(msg != nullptr);
|
||||||
|
|
||||||
int ret = ioctl(fd, request, value_r);
|
int ret = ioctl(fd.Get(), request, value_r);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|
||||||
@@ -281,7 +275,7 @@ oss_try_ioctl_r(int fd, unsigned long request, int *value_r,
|
|||||||
* returned. Any other failure throws std::runtime_error.
|
* returned. Any other failure throws std::runtime_error.
|
||||||
*/
|
*/
|
||||||
static enum oss_setup_result
|
static enum oss_setup_result
|
||||||
oss_try_ioctl(int fd, unsigned long request, int value,
|
oss_try_ioctl(FileDescriptor fd, unsigned long request, int value,
|
||||||
const char *msg)
|
const char *msg)
|
||||||
{
|
{
|
||||||
return oss_try_ioctl_r(fd, request, &value, msg);
|
return oss_try_ioctl_r(fd, request, &value, msg);
|
||||||
@@ -294,7 +288,7 @@ oss_try_ioctl(int fd, unsigned long request, int value,
|
|||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
oss_setup_channels(int fd, AudioFormat &audio_format)
|
oss_setup_channels(FileDescriptor fd, AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
const char *const msg = "Failed to set channel count";
|
const char *const msg = "Failed to set channel count";
|
||||||
int channels = audio_format.channels;
|
int channels = audio_format.channels;
|
||||||
@@ -343,7 +337,7 @@ oss_setup_channels(int fd, AudioFormat &audio_format)
|
|||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
oss_setup_sample_rate(int fd, AudioFormat &audio_format)
|
oss_setup_sample_rate(FileDescriptor fd, AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
const char *const msg = "Failed to set sample rate";
|
const char *const msg = "Failed to set sample rate";
|
||||||
int sample_rate = audio_format.sample_rate;
|
int sample_rate = audio_format.sample_rate;
|
||||||
@@ -467,7 +461,7 @@ sample_format_from_oss(int format) noexcept
|
|||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
static enum oss_setup_result
|
static enum oss_setup_result
|
||||||
oss_probe_sample_format(int fd, SampleFormat sample_format,
|
oss_probe_sample_format(FileDescriptor fd, SampleFormat sample_format,
|
||||||
SampleFormat *sample_format_r,
|
SampleFormat *sample_format_r,
|
||||||
int *oss_format_r
|
int *oss_format_r
|
||||||
#ifdef AFMT_S24_PACKED
|
#ifdef AFMT_S24_PACKED
|
||||||
@@ -523,7 +517,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
|
|||||||
* specified format is not supported.
|
* specified format is not supported.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
oss_setup_sample_format(int fd, AudioFormat &audio_format,
|
oss_setup_sample_format(FileDescriptor fd, AudioFormat &audio_format,
|
||||||
int *oss_format_r
|
int *oss_format_r
|
||||||
#ifdef AFMT_S24_PACKED
|
#ifdef AFMT_S24_PACKED
|
||||||
, PcmExport &pcm_export
|
, PcmExport &pcm_export
|
||||||
@@ -601,10 +595,9 @@ OssOutput::Setup(AudioFormat &_audio_format)
|
|||||||
inline void
|
inline void
|
||||||
OssOutput::Reopen()
|
OssOutput::Reopen()
|
||||||
try {
|
try {
|
||||||
assert(fd < 0);
|
assert(!fd.IsDefined());
|
||||||
|
|
||||||
fd = open_cloexec(device, O_WRONLY, 0);
|
if (!fd.Open(device, O_WRONLY))
|
||||||
if (fd < 0)
|
|
||||||
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
||||||
|
|
||||||
enum oss_setup_result result;
|
enum oss_setup_result result;
|
||||||
@@ -641,8 +634,7 @@ try {
|
|||||||
void
|
void
|
||||||
OssOutput::Open(AudioFormat &_audio_format)
|
OssOutput::Open(AudioFormat &_audio_format)
|
||||||
try {
|
try {
|
||||||
fd = open_cloexec(device, O_WRONLY, 0);
|
if (!fd.Open(device, O_WRONLY))
|
||||||
if (fd < 0)
|
|
||||||
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
||||||
|
|
||||||
Setup(_audio_format);
|
Setup(_audio_format);
|
||||||
@@ -656,8 +648,8 @@ try {
|
|||||||
void
|
void
|
||||||
OssOutput::Cancel() noexcept
|
OssOutput::Cancel() noexcept
|
||||||
{
|
{
|
||||||
if (fd >= 0) {
|
if (fd.IsDefined()) {
|
||||||
ioctl(fd, SNDCTL_DSP_RESET, 0);
|
ioctl(fd.Get(), SNDCTL_DSP_RESET, 0);
|
||||||
DoClose();
|
DoClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,7 +666,7 @@ OssOutput::Play(const void *chunk, size_t size)
|
|||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
/* reopen the device since it was closed by dropBufferedAudio */
|
/* reopen the device since it was closed by dropBufferedAudio */
|
||||||
if (fd < 0)
|
if (!fd.IsDefined())
|
||||||
Reopen();
|
Reopen();
|
||||||
|
|
||||||
#ifdef AFMT_S24_PACKED
|
#ifdef AFMT_S24_PACKED
|
||||||
@@ -686,7 +678,7 @@ OssOutput::Play(const void *chunk, size_t size)
|
|||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ret = write(fd, chunk, size);
|
ret = fd.Write(chunk, size);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
#ifdef AFMT_S24_PACKED
|
#ifdef AFMT_S24_PACKED
|
||||||
ret = pcm_export->CalcSourceSize(ret);
|
ret = pcm_export->CalcSourceSize(ret);
|
||||||
|
Reference in New Issue
Block a user