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
9179d959
Commit
9179d959
authored
Dec 24, 2011
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/osx: allocate the device in enable()
Keep the device open as long as the output is enabled, but initialize it only when playback starts.
parent
f2082174
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
116 additions
and
102 deletions
+116
-102
osx_output_plugin.c
src/output/osx_output_plugin.c
+116
-102
No files found.
src/output/osx_output_plugin.c
View file @
9179d959
...
...
@@ -114,72 +114,6 @@ osx_output_finish(struct audio_output *ao)
g_free
(
od
);
}
static
void
osx_output_cancel
(
struct
audio_output
*
ao
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
g_mutex_lock
(
od
->
mutex
);
od
->
len
=
0
;
g_mutex_unlock
(
od
->
mutex
);
}
static
void
osx_output_close
(
struct
audio_output
*
ao
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
AudioOutputUnitStop
(
od
->
au
);
AudioUnitUninitialize
(
od
->
au
);
CloseComponent
(
od
->
au
);
}
static
OSStatus
osx_render
(
void
*
vdata
,
G_GNUC_UNUSED
AudioUnitRenderActionFlags
*
io_action_flags
,
G_GNUC_UNUSED
const
AudioTimeStamp
*
in_timestamp
,
G_GNUC_UNUSED
UInt32
in_bus_number
,
G_GNUC_UNUSED
UInt32
in_number_frames
,
AudioBufferList
*
buffer_list
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
vdata
;
AudioBuffer
*
buffer
=
&
buffer_list
->
mBuffers
[
0
];
size_t
buffer_size
=
buffer
->
mDataByteSize
;
size_t
bytes_to_copy
;
size_t
trailer_length
;
size_t
dest_pos
=
0
;
g_mutex_lock
(
od
->
mutex
);
bytes_to_copy
=
MIN
(
od
->
len
,
buffer_size
);
od
->
len
-=
bytes_to_copy
;
trailer_length
=
od
->
buffer_size
-
od
->
pos
;
if
(
bytes_to_copy
>
trailer_length
)
{
memcpy
((
unsigned
char
*
)
buffer
->
mData
+
dest_pos
,
od
->
buffer
+
od
->
pos
,
trailer_length
);
od
->
pos
=
0
;
dest_pos
+=
trailer_length
;
bytes_to_copy
-=
trailer_length
;
}
memcpy
((
unsigned
char
*
)
buffer
->
mData
+
dest_pos
,
od
->
buffer
+
od
->
pos
,
bytes_to_copy
);
od
->
pos
+=
bytes_to_copy
;
if
(
od
->
pos
>=
od
->
buffer_size
)
od
->
pos
=
0
;
g_cond_signal
(
od
->
condition
);
g_mutex_unlock
(
od
->
mutex
);
if
(
bytes_to_copy
<
buffer_size
)
memset
((
unsigned
char
*
)
buffer
->
mData
+
bytes_to_copy
,
0
,
buffer_size
-
bytes_to_copy
);
return
0
;
}
static
bool
osx_output_set_device
(
struct
osx_output
*
oo
,
GError
**
error
)
{
...
...
@@ -269,65 +203,135 @@ done:
return
ret
;
}
static
OSStatus
osx_render
(
void
*
vdata
,
G_GNUC_UNUSED
AudioUnitRenderActionFlags
*
io_action_flags
,
G_GNUC_UNUSED
const
AudioTimeStamp
*
in_timestamp
,
G_GNUC_UNUSED
UInt32
in_bus_number
,
G_GNUC_UNUSED
UInt32
in_number_frames
,
AudioBufferList
*
buffer_list
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
vdata
;
AudioBuffer
*
buffer
=
&
buffer_list
->
mBuffers
[
0
];
size_t
buffer_size
=
buffer
->
mDataByteSize
;
size_t
bytes_to_copy
;
size_t
trailer_length
;
size_t
dest_pos
=
0
;
g_mutex_lock
(
od
->
mutex
);
bytes_to_copy
=
MIN
(
od
->
len
,
buffer_size
);
od
->
len
-=
bytes_to_copy
;
trailer_length
=
od
->
buffer_size
-
od
->
pos
;
if
(
bytes_to_copy
>
trailer_length
)
{
memcpy
((
unsigned
char
*
)
buffer
->
mData
+
dest_pos
,
od
->
buffer
+
od
->
pos
,
trailer_length
);
od
->
pos
=
0
;
dest_pos
+=
trailer_length
;
bytes_to_copy
-=
trailer_length
;
}
memcpy
((
unsigned
char
*
)
buffer
->
mData
+
dest_pos
,
od
->
buffer
+
od
->
pos
,
bytes_to_copy
);
od
->
pos
+=
bytes_to_copy
;
if
(
od
->
pos
>=
od
->
buffer_size
)
od
->
pos
=
0
;
g_cond_signal
(
od
->
condition
);
g_mutex_unlock
(
od
->
mutex
);
if
(
bytes_to_copy
<
buffer_size
)
memset
((
unsigned
char
*
)
buffer
->
mData
+
bytes_to_copy
,
0
,
buffer_size
-
bytes_to_copy
);
return
0
;
}
static
bool
osx_output_
open
(
struct
audio_output
*
ao
,
struct
audio_format
*
audio_format
,
GError
**
erro
r
)
osx_output_
enable
(
struct
audio_output
*
ao
,
GError
**
error_
r
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
ComponentDescription
desc
;
Component
comp
;
AURenderCallbackStruct
callback
;
AudioStreamBasicDescription
stream_description
;
OSStatus
status
;
ComponentResult
result
;
struct
osx_output
*
oo
=
(
struct
osx_output
*
)
ao
;
ComponentDescription
desc
;
desc
.
componentType
=
kAudioUnitType_Output
;
desc
.
componentSubType
=
o
d
->
component_subtype
;
desc
.
componentSubType
=
o
o
->
component_subtype
;
desc
.
componentManufacturer
=
kAudioUnitManufacturer_Apple
;
desc
.
componentFlags
=
0
;
desc
.
componentFlagsMask
=
0
;
comp
=
FindNextComponent
(
NULL
,
&
desc
);
Component
comp
=
FindNextComponent
(
NULL
,
&
desc
);
if
(
comp
==
0
)
{
g_set_error
(
error
,
osx_output_quark
(),
0
,
g_set_error
(
error
_r
,
osx_output_quark
(),
0
,
"Error finding OS X component"
);
return
false
;
}
status
=
OpenAComponent
(
comp
,
&
od
->
au
);
OSStatus
status
=
OpenAComponent
(
comp
,
&
oo
->
au
);
if
(
status
!=
noErr
)
{
g_set_error
(
error
,
osx_output_quark
(),
status
,
g_set_error
(
error
_r
,
osx_output_quark
(),
status
,
"Unable to open OS X component: %s"
,
GetMacOSStatusCommentString
(
status
));
return
false
;
}
status
=
AudioUnitInitialize
(
od
->
au
);
if
(
status
!=
noErr
)
{
CloseComponent
(
od
->
au
);
g_set_error
(
error
,
osx_output_quark
(),
status
,
"Unable to initialize OS X audio unit: %s"
,
GetMacOSStatusCommentString
(
status
));
if
(
!
osx_output_set_device
(
oo
,
error_r
))
{
CloseComponent
(
oo
->
au
);
return
false
;
}
if
(
!
osx_output_set_device
(
od
,
error
))
return
false
;
AURenderCallbackStruct
callback
;
callback
.
inputProc
=
osx_render
;
callback
.
inputProcRefCon
=
o
d
;
callback
.
inputProcRefCon
=
o
o
;
result
=
AudioUnitSetProperty
(
od
->
au
,
kAudioUnitProperty_SetRenderCallback
,
kAudioUnitScope_Input
,
0
,
&
callback
,
sizeof
(
callback
));
ComponentResult
result
=
AudioUnitSetProperty
(
oo
->
au
,
kAudioUnitProperty_SetRenderCallback
,
kAudioUnitScope_Input
,
0
,
&
callback
,
sizeof
(
callback
));
if
(
result
!=
noErr
)
{
AudioUnitUninitialize
(
od
->
au
);
CloseComponent
(
od
->
au
);
g_set_error
(
error
,
osx_output_quark
(),
result
,
g_set_error
(
error_r
,
osx_output_quark
(),
result
,
"unable to set callback for OS X audio unit"
);
return
false
;
}
return
true
;
}
static
void
osx_output_disable
(
struct
audio_output
*
ao
)
{
struct
osx_output
*
oo
=
(
struct
osx_output
*
)
ao
;
CloseComponent
(
oo
->
au
);
}
static
void
osx_output_cancel
(
struct
audio_output
*
ao
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
g_mutex_lock
(
od
->
mutex
);
od
->
len
=
0
;
g_mutex_unlock
(
od
->
mutex
);
}
static
void
osx_output_close
(
struct
audio_output
*
ao
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
AudioOutputUnitStop
(
od
->
au
);
AudioUnitUninitialize
(
od
->
au
);
}
static
bool
osx_output_open
(
struct
audio_output
*
ao
,
struct
audio_format
*
audio_format
,
GError
**
error
)
{
struct
osx_output
*
od
=
(
struct
osx_output
*
)
ao
;
AudioStreamBasicDescription
stream_description
;
stream_description
.
mSampleRate
=
audio_format
->
sample_rate
;
stream_description
.
mFormatID
=
kAudioFormatLinearPCM
;
stream_description
.
mFormatFlags
=
kLinearPCMFormatFlagIsSignedInteger
;
...
...
@@ -357,18 +361,25 @@ osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GErr
stream_description
.
mBytesPerFrame
=
stream_description
.
mBytesPerPacket
;
stream_description
.
mChannelsPerFrame
=
audio_format
->
channels
;
result
=
AudioUnitSetProperty
(
od
->
au
,
kAudioUnitProperty_StreamFormat
,
kAudioUnitScope_Input
,
0
,
&
stream_description
,
sizeof
(
stream_description
));
ComponentResult
result
=
AudioUnitSetProperty
(
od
->
au
,
kAudioUnitProperty_StreamFormat
,
kAudioUnitScope_Input
,
0
,
&
stream_description
,
sizeof
(
stream_description
));
if
(
result
!=
noErr
)
{
AudioUnitUninitialize
(
od
->
au
);
CloseComponent
(
od
->
au
);
g_set_error
(
error
,
osx_output_quark
(),
result
,
"Unable to set format on OS X device"
);
return
false
;
}
OSStatus
status
=
AudioUnitInitialize
(
od
->
au
);
if
(
status
!=
noErr
)
{
g_set_error
(
error
,
osx_output_quark
(),
status
,
"Unable to initialize OS X audio unit: %s"
,
GetMacOSStatusCommentString
(
status
));
return
false
;
}
/* create a buffer of 1s */
od
->
buffer_size
=
(
audio_format
->
sample_rate
)
*
audio_format_frame_size
(
audio_format
);
...
...
@@ -379,6 +390,7 @@ osx_output_open(struct audio_output *ao, struct audio_format *audio_format, GErr
status
=
AudioOutputUnitStart
(
od
->
au
);
if
(
status
!=
0
)
{
AudioUnitUninitialize
(
od
->
au
);
g_set_error
(
error
,
osx_output_quark
(),
status
,
"unable to start audio output: %s"
,
GetMacOSStatusCommentString
(
status
));
...
...
@@ -427,6 +439,8 @@ const struct audio_output_plugin osx_output_plugin = {
.
test_default_device
=
osx_output_test_default_device
,
.
init
=
osx_output_init
,
.
finish
=
osx_output_finish
,
.
enable
=
osx_output_enable
,
.
disable
=
osx_output_disable
,
.
open
=
osx_output_open
,
.
close
=
osx_output_close
,
.
play
=
osx_output_play
,
...
...
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