Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
67c48f66
Commit
67c48f66
authored
May 13, 2010
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/oss: rewrite of the audio format detection
Removed the "supported" / "unsupported" arrays, and auto-detect on every open() call, just like the ALSA output plugin.
parent
5fa1c703
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
324 additions
and
301 deletions
+324
-301
oss_plugin.c
src/output/oss_plugin.c
+324
-301
No files found.
src/output/oss_plugin.c
View file @
67c48f66
...
...
@@ -30,6 +30,7 @@
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "oss"
...
...
@@ -43,24 +44,12 @@
struct
oss_data
{
int
fd
;
const
char
*
device
;
struct
audio_format
audio_format
;
int
bitFormat
;
int
*
supported
[
3
];
unsigned
num_supported
[
3
];
int
*
unsupported
[
3
];
unsigned
num_unsupported
[
3
];
};
enum
oss_support
{
OSS_SUPPORTED
=
1
,
OSS_UNSUPPORTED
=
0
,
OSS_UNKNOWN
=
-
1
,
};
enum
oss_param
{
OSS_RATE
=
0
,
OSS_CHANNELS
=
1
,
OSS_BITS
=
2
,
/**
* The current input audio format. This is needed to reopen
* the device after cancel().
*/
struct
audio_format
audio_format
;
};
/**
...
...
@@ -72,188 +61,6 @@ oss_output_quark(void)
return
g_quark_from_static_string
(
"oss_output"
);
}
static
enum
oss_param
oss_param_from_ioctl
(
unsigned
param
)
{
enum
oss_param
idx
=
OSS_RATE
;
switch
(
param
)
{
case
SNDCTL_DSP_SPEED
:
idx
=
OSS_RATE
;
break
;
case
SNDCTL_DSP_CHANNELS
:
idx
=
OSS_CHANNELS
;
break
;
case
SNDCTL_DSP_SAMPLESIZE
:
idx
=
OSS_BITS
;
break
;
}
return
idx
;
}
static
bool
oss_find_supported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
for
(
unsigned
i
=
0
;
i
<
od
->
num_supported
[
idx
];
i
++
)
if
(
od
->
supported
[
idx
][
i
]
==
val
)
return
true
;
return
false
;
}
static
bool
oss_can_convert
(
int
idx
,
int
val
)
{
switch
(
idx
)
{
case
OSS_BITS
:
if
(
val
!=
16
)
return
false
;
break
;
case
OSS_CHANNELS
:
if
(
val
!=
2
)
return
false
;
break
;
}
return
true
;
}
static
int
oss_get_supported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
int
ret
=
-
1
;
int
least
=
val
;
int
diff
;
for
(
unsigned
i
=
0
;
i
<
od
->
num_supported
[
idx
];
i
++
)
{
diff
=
od
->
supported
[
idx
][
i
]
-
val
;
if
(
diff
<
0
)
diff
=
-
diff
;
if
(
diff
<
least
)
{
if
(
!
oss_can_convert
(
idx
,
od
->
supported
[
idx
][
i
]))
continue
;
least
=
diff
;
ret
=
od
->
supported
[
idx
][
i
];
}
}
return
ret
;
}
static
bool
oss_find_unsupported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
for
(
unsigned
i
=
0
;
i
<
od
->
num_unsupported
[
idx
];
i
++
)
{
if
(
od
->
unsupported
[
idx
][
i
]
==
val
)
return
true
;
}
return
false
;
}
static
void
oss_add_supported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
od
->
num_supported
[
idx
]
++
;
od
->
supported
[
idx
]
=
g_realloc
(
od
->
supported
[
idx
],
od
->
num_supported
[
idx
]
*
sizeof
(
int
));
od
->
supported
[
idx
][
od
->
num_supported
[
idx
]
-
1
]
=
val
;
}
static
void
oss_add_unsupported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
od
->
num_unsupported
[
idx
]
++
;
od
->
unsupported
[
idx
]
=
g_realloc
(
od
->
unsupported
[
idx
],
od
->
num_unsupported
[
idx
]
*
sizeof
(
int
));
od
->
unsupported
[
idx
][
od
->
num_unsupported
[
idx
]
-
1
]
=
val
;
}
static
void
oss_remove_supported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
unsigned
j
=
0
;
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
for
(
unsigned
i
=
0
;
i
<
od
->
num_supported
[
idx
]
-
1
;
i
++
)
{
if
(
od
->
supported
[
idx
][
i
]
==
val
)
j
=
1
;
od
->
supported
[
idx
][
i
]
=
od
->
supported
[
idx
][
i
+
j
];
}
od
->
num_supported
[
idx
]
--
;
od
->
supported
[
idx
]
=
g_realloc
(
od
->
supported
[
idx
],
od
->
num_supported
[
idx
]
*
sizeof
(
int
));
}
static
void
oss_remove_unsupported_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
unsigned
j
=
0
;
enum
oss_param
idx
=
oss_param_from_ioctl
(
param
);
for
(
unsigned
i
=
0
;
i
<
od
->
num_unsupported
[
idx
]
-
1
;
i
++
)
{
if
(
od
->
unsupported
[
idx
][
i
]
==
val
)
j
=
1
;
od
->
unsupported
[
idx
][
i
]
=
od
->
unsupported
[
idx
][
i
+
j
];
}
od
->
num_unsupported
[
idx
]
--
;
od
->
unsupported
[
idx
]
=
g_realloc
(
od
->
unsupported
[
idx
],
od
->
num_unsupported
[
idx
]
*
sizeof
(
int
));
}
static
enum
oss_support
oss_param_is_supported
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
if
(
oss_find_supported_param
(
od
,
param
,
val
))
return
OSS_SUPPORTED
;
if
(
oss_find_unsupported_param
(
od
,
param
,
val
))
return
OSS_UNSUPPORTED
;
return
OSS_UNKNOWN
;
}
static
void
oss_set_supported
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_support
supported
=
oss_param_is_supported
(
od
,
param
,
val
);
if
(
supported
==
OSS_SUPPORTED
)
return
;
if
(
supported
==
OSS_UNSUPPORTED
)
oss_remove_unsupported_param
(
od
,
param
,
val
);
oss_add_supported_param
(
od
,
param
,
val
);
}
static
void
oss_set_unsupported
(
struct
oss_data
*
od
,
unsigned
param
,
int
val
)
{
enum
oss_support
supported
=
oss_param_is_supported
(
od
,
param
,
val
);
if
(
supported
==
OSS_UNSUPPORTED
)
return
;
if
(
supported
==
OSS_SUPPORTED
)
oss_remove_supported_param
(
od
,
param
,
val
);
oss_add_unsupported_param
(
od
,
param
,
val
);
}
static
struct
oss_data
*
oss_data_new
(
void
)
{
...
...
@@ -262,38 +69,12 @@ oss_data_new(void)
ret
->
device
=
NULL
;
ret
->
fd
=
-
1
;
ret
->
supported
[
OSS_RATE
]
=
NULL
;
ret
->
supported
[
OSS_CHANNELS
]
=
NULL
;
ret
->
supported
[
OSS_BITS
]
=
NULL
;
ret
->
unsupported
[
OSS_RATE
]
=
NULL
;
ret
->
unsupported
[
OSS_CHANNELS
]
=
NULL
;
ret
->
unsupported
[
OSS_BITS
]
=
NULL
;
ret
->
num_supported
[
OSS_RATE
]
=
0
;
ret
->
num_supported
[
OSS_CHANNELS
]
=
0
;
ret
->
num_supported
[
OSS_BITS
]
=
0
;
ret
->
num_unsupported
[
OSS_RATE
]
=
0
;
ret
->
num_unsupported
[
OSS_CHANNELS
]
=
0
;
ret
->
num_unsupported
[
OSS_BITS
]
=
0
;
oss_set_supported
(
ret
,
SNDCTL_DSP_SPEED
,
48000
);
oss_set_supported
(
ret
,
SNDCTL_DSP_SPEED
,
44100
);
oss_set_supported
(
ret
,
SNDCTL_DSP_CHANNELS
,
2
);
oss_set_supported
(
ret
,
SNDCTL_DSP_SAMPLESIZE
,
16
);
return
ret
;
}
static
void
oss_data_free
(
struct
oss_data
*
od
)
{
g_free
(
od
->
supported
[
OSS_RATE
]);
g_free
(
od
->
supported
[
OSS_CHANNELS
]);
g_free
(
od
->
supported
[
OSS_BITS
]);
g_free
(
od
->
unsupported
[
OSS_RATE
]);
g_free
(
od
->
unsupported
[
OSS_CHANNELS
]);
g_free
(
od
->
unsupported
[
OSS_BITS
]);
g_free
(
od
);
}
...
...
@@ -417,37 +198,6 @@ oss_output_finish(void *data)
oss_data_free
(
od
);
}
static
int
oss_set_param
(
struct
oss_data
*
od
,
unsigned
param
,
int
*
value
)
{
int
val
=
*
value
;
int
copy
;
enum
oss_support
supported
=
oss_param_is_supported
(
od
,
param
,
val
);
do
{
if
(
supported
==
OSS_UNSUPPORTED
)
{
val
=
oss_get_supported_param
(
od
,
param
,
val
);
if
(
copy
<
0
)
return
-
1
;
}
copy
=
val
;
if
(
ioctl
(
od
->
fd
,
param
,
&
copy
))
{
oss_set_unsupported
(
od
,
param
,
val
);
supported
=
OSS_UNSUPPORTED
;
}
else
{
if
(
supported
==
OSS_UNKNOWN
)
{
oss_set_supported
(
od
,
param
,
val
);
supported
=
OSS_SUPPORTED
;
}
val
=
copy
;
}
}
while
(
supported
==
OSS_UNSUPPORTED
);
*
value
=
val
;
return
0
;
}
static
void
oss_close
(
struct
oss_data
*
od
)
{
...
...
@@ -457,75 +207,343 @@ oss_close(struct oss_data *od)
}
/**
*
Sets up the OSS device which was opened before
.
*
A tri-state type for oss_try_ioctl()
.
*/
static
bool
oss_setup
(
struct
oss_data
*
od
,
GError
**
error
)
enum
oss_setup_result
{
SUCCESS
,
ERROR
,
UNSUPPORTED
,
};
/**
* Invoke an ioctl on the OSS file descriptor. On success, SUCCESS is
* returned. If the parameter is not supported, UNSUPPORTED is
* returned. Any other failure returns ERROR and allocates a GError.
*/
static
enum
oss_setup_result
oss_try_ioctl_r
(
int
fd
,
unsigned
long
request
,
int
*
value_r
,
const
char
*
msg
,
GError
**
error_r
)
{
int
tmp
;
assert
(
fd
>=
0
);
assert
(
value_r
!=
NULL
);
assert
(
msg
!=
NULL
);
assert
(
error_r
==
NULL
||
*
error_r
==
NULL
);
tmp
=
od
->
audio_format
.
channels
;
if
(
oss_set_param
(
od
,
SNDCTL_DSP_CHANNELS
,
&
tmp
))
{
g_set_error
(
error
,
oss_output_quark
(),
errno
,
"OSS device
\"
%s
\"
does not support %u channels: %s"
,
od
->
device
,
od
->
audio_format
.
channels
,
strerror
(
errno
));
int
ret
=
ioctl
(
fd
,
request
,
value_r
);
if
(
ret
>=
0
)
return
SUCCESS
;
if
(
errno
==
EINVAL
)
return
UNSUPPORTED
;
g_set_error
(
error_r
,
oss_output_quark
(),
errno
,
"%s: %s"
,
msg
,
g_strerror
(
errno
));
return
ERROR
;
}
/**
* Invoke an ioctl on the OSS file descriptor. On success, SUCCESS is
* returned. If the parameter is not supported, UNSUPPORTED is
* returned. Any other failure returns ERROR and allocates a GError.
*/
static
enum
oss_setup_result
oss_try_ioctl
(
int
fd
,
unsigned
long
request
,
int
value
,
const
char
*
msg
,
GError
**
error_r
)
{
return
oss_try_ioctl_r
(
fd
,
request
,
&
value
,
msg
,
error_r
);
}
/**
* Set up the channel number, and attempts to find alternatives if the
* specified number is not supported.
*/
static
bool
oss_setup_channels
(
int
fd
,
struct
audio_format
*
audio_format
,
GError
**
error_r
)
{
const
char
*
const
msg
=
"Failed to set channel count"
;
int
channels
=
audio_format
->
channels
;
enum
oss_setup_result
result
=
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_CHANNELS
,
&
channels
,
msg
,
error_r
);
switch
(
result
)
{
case
SUCCESS
:
if
(
!
audio_valid_channel_count
(
channels
))
break
;
audio_format
->
channels
=
channels
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
od
->
audio_format
.
channels
=
tmp
;
tmp
=
od
->
audio_format
.
sample_rate
;
if
(
oss_set_param
(
od
,
SNDCTL_DSP_SPEED
,
&
tmp
))
{
g_set_error
(
error
,
oss_output_quark
(),
errno
,
"OSS device
\"
%s
\"
does not support %u Hz audio: %s"
,
od
->
device
,
od
->
audio_format
.
sample_rate
,
strerror
(
errno
));
for
(
unsigned
i
=
1
;
i
<
2
;
++
i
)
{
if
(
i
==
audio_format
->
channels
)
/* don't try that again */
continue
;
channels
=
i
;
result
=
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_CHANNELS
,
&
channels
,
msg
,
error_r
);
switch
(
result
)
{
case
SUCCESS
:
if
(
!
audio_valid_channel_count
(
channels
))
break
;
audio_format
->
channels
=
channels
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
}
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg
);
return
false
;
}
/**
* Set up the sample rate, and attempts to find alternatives if the
* specified sample rate is not supported.
*/
static
bool
oss_setup_sample_rate
(
int
fd
,
struct
audio_format
*
audio_format
,
GError
**
error_r
)
{
const
char
*
const
msg
=
"Failed to set sample rate"
;
int
sample_rate
=
audio_format
->
sample_rate
;
enum
oss_setup_result
result
=
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_SPEED
,
&
sample_rate
,
msg
,
error_r
);
switch
(
result
)
{
case
SUCCESS
:
if
(
!
audio_valid_sample_rate
(
sample_rate
))
break
;
audio_format
->
sample_rate
=
sample_rate
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
static
const
int
sample_rates
[]
=
{
48000
,
44100
,
0
};
for
(
unsigned
i
=
0
;
sample_rates
[
i
]
!=
0
;
++
i
)
{
sample_rate
=
sample_rates
[
i
];
if
(
sample_rate
==
(
int
)
audio_format
->
sample_rate
)
continue
;
result
=
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_SPEED
,
&
sample_rate
,
msg
,
error_r
);
switch
(
result
)
{
case
SUCCESS
:
if
(
!
audio_valid_sample_rate
(
sample_rate
))
break
;
audio_format
->
sample_rate
=
sample_rate
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
}
od
->
audio_format
.
sample_rate
=
tmp
;
switch
(
od
->
audio_format
.
format
)
{
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg
);
return
false
;
}
/**
* Convert a MPD sample format to its OSS counterpart. Returns
* AFMT_QUERY if there is no direct counterpart.
*/
static
int
sample_format_to_oss
(
enum
sample_format
format
)
{
switch
(
format
)
{
case
SAMPLE_FORMAT_UNDEFINED
:
return
AFMT_QUERY
;
case
SAMPLE_FORMAT_S8
:
tmp
=
AFMT_S8
;
break
;
return
AFMT_S8
;
case
SAMPLE_FORMAT_S16
:
tmp
=
AFMT_S16_NE
;
break
;
return
AFMT_S16_NE
;
case
SAMPLE_FORMAT_S24
:
case
SAMPLE_FORMAT_S24_P32
:
case
SAMPLE_FORMAT_S32
:
return
AFMT_QUERY
;
}
return
AFMT_QUERY
;
}
/**
* Convert an OSS sample format to its MPD counterpart. Returns
* SAMPLE_FORMAT_UNDEFINED if there is no direct counterpart.
*/
static
enum
sample_format
sample_format_from_oss
(
int
format
)
{
switch
(
format
)
{
case
AFMT_S8
:
return
SAMPLE_FORMAT_S8
;
case
AFMT_S16_NE
:
return
SAMPLE_FORMAT_S16
;
default:
/* not supported by OSS - fall back to 16 bit */
od
->
audio_format
.
format
=
SAMPLE_FORMAT_S16
;
tmp
=
AFMT_S16_NE
;
break
;
return
SAMPLE_FORMAT_UNDEFINED
;
}
}
if
(
oss_set_param
(
od
,
SNDCTL_DSP_SAMPLESIZE
,
&
tmp
))
{
g_set_error
(
error
,
oss_output_quark
(),
errno
,
"OSS device
\"
%s
\"
does not support %u bit audio: %s"
,
od
->
device
,
tmp
,
strerror
(
errno
));
/**
* Set up the sample format, and attempts to find alternatives if the
* specified format is not supported.
*/
static
bool
oss_setup_sample_format
(
int
fd
,
struct
audio_format
*
audio_format
,
GError
**
error_r
)
{
const
char
*
const
msg
=
"Failed to set sample format"
;
int
oss_format
=
sample_format_to_oss
(
audio_format
->
format
);
enum
oss_setup_result
result
=
oss_format
!=
AFMT_QUERY
?
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_SAMPLESIZE
,
&
oss_format
,
msg
,
error_r
)
:
UNSUPPORTED
;
enum
sample_format
mpd_format
;
switch
(
result
)
{
case
SUCCESS
:
mpd_format
=
sample_format_from_oss
(
oss_format
);
if
(
mpd_format
==
SAMPLE_FORMAT_UNDEFINED
)
break
;
audio_format
->
format
=
mpd_format
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
return
true
;
/* the requested sample format is not available - probe for
other formats supported by MPD */
static
const
enum
sample_format
sample_formats
[]
=
{
SAMPLE_FORMAT_S16
,
SAMPLE_FORMAT_S8
,
SAMPLE_FORMAT_UNDEFINED
/* sentinel */
};
for
(
unsigned
i
=
0
;
sample_formats
[
i
]
!=
SAMPLE_FORMAT_UNDEFINED
;
++
i
)
{
mpd_format
=
sample_formats
[
i
];
if
(
mpd_format
==
audio_format
->
format
)
/* don't try that again */
continue
;
oss_format
=
sample_format_to_oss
(
mpd_format
);
if
(
oss_format
==
AFMT_QUERY
)
/* not supported by this OSS version */
continue
;
result
=
oss_try_ioctl_r
(
fd
,
SNDCTL_DSP_SAMPLESIZE
,
&
oss_format
,
msg
,
error_r
);
switch
(
result
)
{
case
SUCCESS
:
mpd_format
=
sample_format_from_oss
(
oss_format
);
if
(
mpd_format
==
SAMPLE_FORMAT_UNDEFINED
)
break
;
audio_format
->
format
=
mpd_format
;
return
true
;
case
ERROR
:
return
false
;
case
UNSUPPORTED
:
break
;
}
}
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg
);
return
false
;
}
/**
* Sets up the OSS device which was opened before.
*/
static
bool
oss_open
(
struct
oss_data
*
od
,
GError
**
error
)
oss_setup
(
struct
oss_data
*
od
,
struct
audio_format
*
audio_format
,
GError
**
error_r
)
{
bool
success
;
return
oss_setup_channels
(
od
->
fd
,
audio_format
,
error_r
)
&&
oss_setup_sample_rate
(
od
->
fd
,
audio_format
,
error_r
)
&&
oss_setup_sample_format
(
od
->
fd
,
audio_format
,
error_r
);
}
/**
* Reopen the device with the saved audio_format, without any probing.
*/
static
bool
oss_reopen
(
struct
oss_data
*
od
,
GError
**
error_r
)
{
assert
(
od
->
fd
<
0
);
od
->
fd
=
open_cloexec
(
od
->
device
,
O_WRONLY
,
0
);
if
(
od
->
fd
<
0
)
{
g_set_error
(
error
,
oss_output_quark
(),
errno
,
g_set_error
(
error
_r
,
oss_output_quark
(),
errno
,
"Error opening OSS device
\"
%s
\"
: %s"
,
od
->
device
,
strerror
(
errno
));
return
false
;
}
success
=
oss_setup
(
od
,
error
);
if
(
!
success
)
{
enum
oss_setup_result
result
;
const
char
*
const
msg1
=
"Failed to set channel count"
;
result
=
oss_try_ioctl
(
od
->
fd
,
SNDCTL_DSP_CHANNELS
,
od
->
audio_format
.
channels
,
msg1
,
error_r
);
if
(
result
!=
SUCCESS
)
{
oss_close
(
od
);
if
(
result
==
UNSUPPORTED
)
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg1
);
return
false
;
}
const
char
*
const
msg2
=
"Failed to set sample rate"
;
result
=
oss_try_ioctl
(
od
->
fd
,
SNDCTL_DSP_SPEED
,
od
->
audio_format
.
sample_rate
,
msg2
,
error_r
);
if
(
result
!=
SUCCESS
)
{
oss_close
(
od
);
if
(
result
==
UNSUPPORTED
)
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg2
);
return
false
;
}
const
char
*
const
msg3
=
"Failed to set sample format"
;
assert
(
sample_format_to_oss
(
od
->
audio_format
.
format
)
!=
AFMT_QUERY
);
result
=
oss_try_ioctl
(
od
->
fd
,
SNDCTL_DSP_SAMPLESIZE
,
sample_format_to_oss
(
od
->
audio_format
.
format
),
msg3
,
error_r
);
if
(
result
!=
SUCCESS
)
{
oss_close
(
od
);
if
(
result
==
UNSUPPORTED
)
g_set_error
(
error_r
,
oss_output_quark
(),
EINVAL
,
"%s"
,
msg3
);
return
false
;
}
...
...
@@ -535,18 +553,23 @@ oss_open(struct oss_data *od, GError **error)
static
bool
oss_output_open
(
void
*
data
,
struct
audio_format
*
audio_format
,
GError
**
error
)
{
bool
ret
;
struct
oss_data
*
od
=
data
;
od
->
audio_format
=
*
audio_format
;
ret
=
oss_open
(
od
,
error
);
if
(
!
ret
)
od
->
fd
=
open_cloexec
(
od
->
device
,
O_WRONLY
,
0
);
if
(
od
->
fd
<
0
)
{
g_set_error
(
error
,
oss_output_quark
(),
errno
,
"Error opening OSS device
\"
%s
\"
: %s"
,
od
->
device
,
strerror
(
errno
));
return
false
;
}
*
audio_format
=
od
->
audio_format
;
if
(
!
oss_setup
(
od
,
audio_format
,
error
))
{
oss_close
(
od
);
return
false
;
}
return
ret
;
od
->
audio_format
=
*
audio_format
;
return
true
;
}
static
void
...
...
@@ -575,7 +598,7 @@ oss_output_play(void *data, const void *chunk, size_t size, GError **error)
ssize_t
ret
;
/* reopen the device since it was closed by dropBufferedAudio */
if
(
od
->
fd
<
0
&&
!
oss_open
(
od
,
error
))
if
(
od
->
fd
<
0
&&
!
oss_
re
open
(
od
,
error
))
return
0
;
while
(
true
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment