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
9cce1d74
Commit
9cce1d74
authored
May 18, 2010
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/win32: new output plugin for Windows Wave
parent
ed0b4804
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
323 additions
and
0 deletions
+323
-0
Makefile.am
Makefile.am
+4
-0
NEWS
NEWS
+1
-0
configure.ac
configure.ac
+18
-0
win32_output_plugin.c
src/output/win32_output_plugin.c
+296
-0
output_list.c
src/output_list.c
+4
-0
No files found.
Makefile.am
View file @
9cce1d74
...
@@ -720,6 +720,10 @@ if ENABLE_SOLARIS_OUTPUT
...
@@ -720,6 +720,10 @@ if ENABLE_SOLARIS_OUTPUT
OUTPUT_SRC
+=
src/output/solaris_output_plugin.c
OUTPUT_SRC
+=
src/output/solaris_output_plugin.c
endif
endif
if
ENABLE_WIN32_OUTPUT
OUTPUT_SRC
+=
src/output/win32_output_plugin.c
endif
#
#
# Playlist plugins
# Playlist plugins
...
...
NEWS
View file @
9cce1d74
...
@@ -58,6 +58,7 @@ ver 0.16 (20??/??/??)
...
@@ -58,6 +58,7 @@ ver 0.16 (20??/??/??)
- httpd: bind port when output is enabled
- httpd: bind port when output is enabled
- httpd: added name/genre/website configuration
- httpd: added name/genre/website configuration
- oss: 24 bit support via OSS4
- oss: 24 bit support via OSS4
- win32: new output plugin for Windows Wave
- wildcards allowed in audio_format configuration
- wildcards allowed in audio_format configuration
- consistently lock audio output objects
- consistently lock audio output objects
* player:
* player:
...
...
configure.ac
View file @
9cce1d74
...
@@ -1372,6 +1372,22 @@ esac
...
@@ -1372,6 +1372,22 @@ esac
AM_CONDITIONAL(ENABLE_SOLARIS_OUTPUT, test x$enable_solaris_output = xyes)
AM_CONDITIONAL(ENABLE_SOLARIS_OUTPUT, test x$enable_solaris_output = xyes)
dnl --------------------------------- Solaris ---------------------------------
case "$host_os" in
mingw32* | windows*)
AC_DEFINE(ENABLE_WIN32_OUTPUT, 1, [Define to enable WIN32 wave support])
enable_win32_output=yes
MPD_LIBS="$MPD_LIBS -lwinmm"
;;
*)
enable_win32_output=no
;;
esac
AM_CONDITIONAL(ENABLE_WIN32_OUTPUT, test x$enable_win32_output = xyes)
dnl --------------------- Post Audio Output Plugins Tests ---------------------
dnl --------------------- Post Audio Output Plugins Tests ---------------------
if
if
test x$enable_alsa = xno &&
test x$enable_alsa = xno &&
...
@@ -1388,6 +1404,7 @@ if
...
@@ -1388,6 +1404,7 @@ if
test x$enable_recorder_output = xno &&
test x$enable_recorder_output = xno &&
test x$enable_shout = xno &&
test x$enable_shout = xno &&
test x$enable_solaris_output = xno &&
test x$enable_solaris_output = xno &&
test x$enable_win32_output = xno &&
AC_MSG_ERROR([No Audio Output types configured!])
AC_MSG_ERROR([No Audio Output types configured!])
fi
fi
...
@@ -1523,6 +1540,7 @@ results(mvp, [Media MVP])
...
@@ -1523,6 +1540,7 @@ results(mvp, [Media MVP])
results(shout, [SHOUTcast])
results(shout, [SHOUTcast])
echo -ne '\n\t'
echo -ne '\n\t'
results(solaris, [Solaris])
results(solaris, [Solaris])
results(win32_output, [WIN32 wave])
if
if
test x$enable_shout = xyes ||
test x$enable_shout = xyes ||
...
...
src/output/win32_output_plugin.c
0 → 100644
View file @
9cce1d74
/*
* Copyright (C) 2003-2010 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "output_api.h"
#include "pcm_buffer.h"
#include <windows.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "win32_output"
struct
win32_buffer
{
struct
pcm_buffer
buffer
;
WAVEHDR
hdr
;
};
struct
win32_output
{
HWAVEOUT
handle
;
/**
* This event is triggered by Windows when a buffer is
* finished.
*/
HANDLE
event
;
struct
win32_buffer
buffers
[
8
];
unsigned
next_buffer
;
};
/**
* The quark used for GError.domain.
*/
static
inline
GQuark
win32_output_quark
(
void
)
{
return
g_quark_from_static_string
(
"win32_output"
);
}
static
bool
win32_output_test_default_device
(
void
)
{
/* we assume that Wave is always available */
return
true
;
}
static
void
*
win32_output_init
(
G_GNUC_UNUSED
const
struct
audio_format
*
audio_format
,
G_GNUC_UNUSED
const
struct
config_param
*
param
,
G_GNUC_UNUSED
GError
**
error
)
{
struct
win32_output
*
wo
=
g_new
(
struct
win32_output
,
1
);
return
wo
;
}
static
void
win32_output_finish
(
void
*
data
)
{
struct
win32_output
*
wo
=
data
;
g_free
(
wo
);
}
static
bool
win32_output_open
(
void
*
data
,
struct
audio_format
*
audio_format
,
GError
**
error_r
)
{
struct
win32_output
*
wo
=
data
;
wo
->
event
=
CreateEvent
(
NULL
,
false
,
false
,
NULL
);
if
(
wo
->
event
==
NULL
)
{
g_set_error
(
error_r
,
win32_output_quark
(),
0
,
"CreateEvent() failed"
);
return
false
;
}
switch
(
audio_format
->
format
)
{
case
SAMPLE_FORMAT_S8
:
case
SAMPLE_FORMAT_S16
:
break
;
case
SAMPLE_FORMAT_S24
:
case
SAMPLE_FORMAT_S24_P32
:
case
SAMPLE_FORMAT_S32
:
case
SAMPLE_FORMAT_UNDEFINED
:
/* we havn't tested formats other than S16 */
audio_format
->
format
=
SAMPLE_FORMAT_S16
;
break
;
}
if
(
audio_format
->
channels
>
2
)
/* same here: more than stereo was not tested */
audio_format
->
channels
=
2
;
WAVEFORMATEX
format
;
format
.
wFormatTag
=
WAVE_FORMAT_PCM
;
format
.
nChannels
=
audio_format
->
channels
;
format
.
nSamplesPerSec
=
audio_format
->
sample_rate
;
format
.
nBlockAlign
=
audio_format_frame_size
(
audio_format
);
format
.
nAvgBytesPerSec
=
format
.
nSamplesPerSec
*
format
.
nBlockAlign
;
format
.
wBitsPerSample
=
audio_format_sample_size
(
audio_format
)
*
8
;
format
.
cbSize
=
0
;
MMRESULT
result
=
waveOutOpen
(
&
wo
->
handle
,
WAVE_MAPPER
,
&
format
,
(
DWORD_PTR
)
wo
->
event
,
0
,
CALLBACK_EVENT
);
if
(
result
!=
MMSYSERR_NOERROR
)
{
CloseHandle
(
wo
->
event
);
g_set_error
(
error_r
,
win32_output_quark
(),
result
,
"waveOutOpen() failed"
);
return
false
;
}
for
(
unsigned
i
=
0
;
i
<
G_N_ELEMENTS
(
wo
->
buffers
);
++
i
)
{
pcm_buffer_init
(
&
wo
->
buffers
[
i
].
buffer
);
memset
(
&
wo
->
buffers
[
i
].
hdr
,
0
,
sizeof
(
wo
->
buffers
[
i
].
hdr
));
}
wo
->
next_buffer
=
0
;
return
true
;
}
static
void
win32_output_close
(
void
*
data
)
{
struct
win32_output
*
wo
=
data
;
for
(
unsigned
i
=
0
;
i
<
G_N_ELEMENTS
(
wo
->
buffers
);
++
i
)
pcm_buffer_deinit
(
&
wo
->
buffers
[
i
].
buffer
);
waveOutClose
(
wo
->
handle
);
CloseHandle
(
wo
->
event
);
}
/**
* Copy data into a buffer, and prepare the wave header.
*/
static
bool
win32_set_buffer
(
struct
win32_output
*
wo
,
struct
win32_buffer
*
buffer
,
const
void
*
data
,
size_t
size
,
GError
**
error_r
)
{
void
*
dest
=
pcm_buffer_get
(
&
buffer
->
buffer
,
size
);
if
(
dest
==
NULL
)
{
g_set_error
(
error_r
,
win32_output_quark
(),
0
,
"Out of memory"
);
return
false
;
}
memcpy
(
dest
,
data
,
size
);
memset
(
&
buffer
->
hdr
,
0
,
sizeof
(
buffer
->
hdr
));
buffer
->
hdr
.
lpData
=
dest
;
buffer
->
hdr
.
dwBufferLength
=
size
;
MMRESULT
result
=
waveOutPrepareHeader
(
wo
->
handle
,
&
buffer
->
hdr
,
sizeof
(
buffer
->
hdr
));
if
(
result
!=
MMSYSERR_NOERROR
)
{
g_set_error
(
error_r
,
win32_output_quark
(),
result
,
"waveOutPrepareHeader() failed"
);
return
false
;
}
return
true
;
}
/**
* Wait until the buffer is finished.
*/
static
bool
win32_drain_buffer
(
struct
win32_output
*
wo
,
struct
win32_buffer
*
buffer
,
GError
**
error_r
)
{
if
((
buffer
->
hdr
.
dwFlags
&
WHDR_DONE
)
==
WHDR_DONE
)
/* already finished */
return
true
;
while
(
true
)
{
MMRESULT
result
=
waveOutUnprepareHeader
(
wo
->
handle
,
&
buffer
->
hdr
,
sizeof
(
buffer
->
hdr
));
if
(
result
==
MMSYSERR_NOERROR
)
return
true
;
else
if
(
result
!=
WAVERR_STILLPLAYING
)
{
g_set_error
(
error_r
,
win32_output_quark
(),
result
,
"waveOutUnprepareHeader() failed"
);
return
false
;
}
/* wait some more */
WaitForSingleObject
(
wo
->
event
,
INFINITE
);
}
}
static
size_t
win32_output_play
(
void
*
data
,
const
void
*
chunk
,
size_t
size
,
GError
**
error_r
)
{
struct
win32_output
*
wo
=
data
;
/* get the next buffer from the ring and prepare it */
struct
win32_buffer
*
buffer
=
&
wo
->
buffers
[
wo
->
next_buffer
];
if
(
!
win32_drain_buffer
(
wo
,
buffer
,
error_r
)
||
!
win32_set_buffer
(
wo
,
buffer
,
chunk
,
size
,
error_r
))
return
0
;
/* enqueue the buffer */
MMRESULT
result
=
waveOutWrite
(
wo
->
handle
,
&
buffer
->
hdr
,
sizeof
(
buffer
->
hdr
));
if
(
result
!=
MMSYSERR_NOERROR
)
{
waveOutUnprepareHeader
(
wo
->
handle
,
&
buffer
->
hdr
,
sizeof
(
buffer
->
hdr
));
g_set_error
(
error_r
,
win32_output_quark
(),
result
,
"waveOutWrite() failed"
);
return
0
;
}
/* mark our buffer as "used" */
wo
->
next_buffer
=
(
wo
->
next_buffer
+
1
)
%
G_N_ELEMENTS
(
wo
->
buffers
);
return
size
;
}
static
bool
win32_drain_all_buffers
(
struct
win32_output
*
wo
,
GError
**
error_r
)
{
for
(
unsigned
i
=
wo
->
next_buffer
;
i
<
G_N_ELEMENTS
(
wo
->
buffers
);
++
i
)
if
(
!
win32_drain_buffer
(
wo
,
&
wo
->
buffers
[
i
],
error_r
))
return
false
;
for
(
unsigned
i
=
0
;
i
<
wo
->
next_buffer
;
++
i
)
if
(
!
win32_drain_buffer
(
wo
,
&
wo
->
buffers
[
i
],
error_r
))
return
false
;
return
true
;
}
static
void
win32_stop
(
struct
win32_output
*
wo
)
{
waveOutReset
(
wo
->
handle
);
for
(
unsigned
i
=
0
;
i
<
G_N_ELEMENTS
(
wo
->
buffers
);
++
i
)
{
struct
win32_buffer
*
buffer
=
&
wo
->
buffers
[
i
];
waveOutUnprepareHeader
(
wo
->
handle
,
&
buffer
->
hdr
,
sizeof
(
buffer
->
hdr
));
}
}
static
void
win32_output_drain
(
void
*
data
)
{
struct
win32_output
*
wo
=
data
;
if
(
!
win32_drain_all_buffers
(
wo
,
NULL
))
win32_stop
(
wo
);
}
static
void
win32_output_cancel
(
void
*
data
)
{
struct
win32_output
*
wo
=
data
;
win32_stop
(
wo
);
}
const
struct
audio_output_plugin
win32_output_plugin
=
{
.
name
=
"win32"
,
.
test_default_device
=
win32_output_test_default_device
,
.
init
=
win32_output_init
,
.
finish
=
win32_output_finish
,
.
open
=
win32_output_open
,
.
close
=
win32_output_close
,
.
play
=
win32_output_play
,
.
drain
=
win32_output_drain
,
.
cancel
=
win32_output_cancel
,
};
src/output_list.c
View file @
9cce1d74
...
@@ -36,6 +36,7 @@ extern const struct audio_output_plugin mvp_output_plugin;
...
@@ -36,6 +36,7 @@ extern const struct audio_output_plugin mvp_output_plugin;
extern
const
struct
audio_output_plugin
jack_output_plugin
;
extern
const
struct
audio_output_plugin
jack_output_plugin
;
extern
const
struct
audio_output_plugin
httpd_output_plugin
;
extern
const
struct
audio_output_plugin
httpd_output_plugin
;
extern
const
struct
audio_output_plugin
recorder_output_plugin
;
extern
const
struct
audio_output_plugin
recorder_output_plugin
;
extern
const
struct
audio_output_plugin
win32_output_plugin
;
const
struct
audio_output_plugin
*
audio_output_plugins
[]
=
{
const
struct
audio_output_plugin
*
audio_output_plugins
[]
=
{
#ifdef HAVE_SHOUT
#ifdef HAVE_SHOUT
...
@@ -81,6 +82,9 @@ const struct audio_output_plugin *audio_output_plugins[] = {
...
@@ -81,6 +82,9 @@ const struct audio_output_plugin *audio_output_plugins[] = {
#ifdef ENABLE_RECORDER_OUTPUT
#ifdef ENABLE_RECORDER_OUTPUT
&
recorder_output_plugin
,
&
recorder_output_plugin
,
#endif
#endif
#ifdef ENABLE_WIN32_OUTPUT
&
win32_output_plugin
,
#endif
NULL
NULL
};
};
...
...
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