mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 623444 - Import Windows libcubeb implementation. r=doublec, r=khuey
This commit is contained in:
parent
1e41289b57
commit
a7fb4781d7
@ -160,6 +160,7 @@ MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
|
||||
MOZ_OGG = @MOZ_OGG@
|
||||
MOZ_RAW = @MOZ_RAW@
|
||||
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
||||
MOZ_CUBEB = @MOZ_CUBEB@
|
||||
MOZ_WAVE = @MOZ_WAVE@
|
||||
MOZ_MEDIA = @MOZ_MEDIA@
|
||||
MOZ_VORBIS = @MOZ_VORBIS@
|
||||
|
@ -1050,4 +1050,5 @@ tremor/ivorbiscodec.h
|
||||
ogg/ogg.h
|
||||
ogg/os_types.h
|
||||
nestegg/nestegg.h
|
||||
cubeb/cubeb.h
|
||||
#endif
|
||||
|
18
configure.in
18
configure.in
@ -4586,6 +4586,7 @@ MOZ_AUTH_EXTENSION=1
|
||||
MOZ_OGG=1
|
||||
MOZ_RAW=
|
||||
MOZ_SYDNEYAUDIO=
|
||||
MOZ_CUBEB=
|
||||
MOZ_VORBIS=
|
||||
MOZ_TREMOR=
|
||||
MOZ_WAVE=1
|
||||
@ -5596,6 +5597,7 @@ MOZ_ARG_DISABLE_BOOL(ogg,
|
||||
if test -n "$MOZ_OGG"; then
|
||||
AC_DEFINE(MOZ_OGG)
|
||||
MOZ_SYDNEYAUDIO=1
|
||||
MOZ_CUBEB=1
|
||||
MOZ_MEDIA=1
|
||||
case "$target_cpu" in
|
||||
arm*)
|
||||
@ -5713,6 +5715,7 @@ AC_SUBST(MOZ_LIBVPX_LIBS)
|
||||
|
||||
if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
|
||||
MOZ_SYDNEYAUDIO=1
|
||||
MOZ_CUBEB=1
|
||||
MOZ_MEDIA=1
|
||||
case "$target_cpu" in
|
||||
arm*)
|
||||
@ -5824,17 +5827,29 @@ MOZ_ARG_DISABLE_BOOL(wave,
|
||||
if test -n "$MOZ_WAVE"; then
|
||||
AC_DEFINE(MOZ_WAVE)
|
||||
MOZ_SYDNEYAUDIO=1
|
||||
MOZ_CUBEB=1
|
||||
MOZ_MEDIA=1
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Handle dependent SYDNEYAUDIO and MEDIA defines
|
||||
dnl = Handle dependent SYDNEYAUDIO, CUBEB, and MEDIA defines
|
||||
dnl ========================================================
|
||||
|
||||
if test -n "$MOZ_SYDNEYAUDIO"; then
|
||||
AC_DEFINE(MOZ_SYDNEYAUDIO)
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_CUBEB"; then
|
||||
case "$target" in
|
||||
*-mingw*)
|
||||
AC_DEFINE(MOZ_CUBEB)
|
||||
;;
|
||||
*)
|
||||
dnl Other targets will be enabled soon.
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_MEDIA"; then
|
||||
AC_DEFINE(MOZ_MEDIA)
|
||||
fi
|
||||
@ -8696,6 +8711,7 @@ AC_SUBST(MOZ_APP_EXTRA_LIBS)
|
||||
|
||||
AC_SUBST(MOZ_MEDIA)
|
||||
AC_SUBST(MOZ_SYDNEYAUDIO)
|
||||
AC_SUBST(MOZ_CUBEB)
|
||||
AC_SUBST(MOZ_WAVE)
|
||||
AC_SUBST(MOZ_VORBIS)
|
||||
AC_SUBST(MOZ_TREMOR)
|
||||
|
@ -1050,4 +1050,5 @@ tremor/ivorbiscodec.h
|
||||
ogg/ogg.h
|
||||
ogg/os_types.h
|
||||
nestegg/nestegg.h
|
||||
cubeb/cubeb.h
|
||||
#endif
|
||||
|
@ -182,10 +182,6 @@ SHARED_LIBRARY_LIBS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_SYDNEYAUDIO
|
||||
LOCAL_INCLUDES += -I$(DEPTH)/content/html/content/src
|
||||
endif
|
||||
|
||||
ifdef NS_PRINTING
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
../printing/$(LIB_PREFIX)gkprinting_s.$(LIB_SUFFIX) \
|
||||
|
@ -86,6 +86,12 @@ SHARED_LIBRARY_LIBS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_CUBEB
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
$(DEPTH)/media/libcubeb/src/$(LIB_PREFIX)cubeb.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
$(DEPTH)/gfx/angle/$(LIB_PREFIX)angle.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
@ -100,6 +106,10 @@ else
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_ZLIB_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_CUBEB
|
||||
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME, winmm ksguid)
|
||||
endif
|
||||
|
||||
DEFFILE = symbols.def
|
||||
endif
|
||||
|
||||
|
@ -73,6 +73,15 @@ sa_stream_pause
|
||||
sa_stream_resume
|
||||
sa_stream_write
|
||||
#endif
|
||||
#ifdef MOZ_CUBEB
|
||||
cubeb_destroy
|
||||
cubeb_init
|
||||
cubeb_stream_destroy
|
||||
cubeb_stream_get_position
|
||||
cubeb_stream_init
|
||||
cubeb_stream_start
|
||||
cubeb_stream_stop
|
||||
#endif
|
||||
#ifdef MOZ_OGG
|
||||
th_comment_clear
|
||||
th_comment_init
|
||||
|
1
media/libcubeb/AUTHORS
Normal file
1
media/libcubeb/AUTHORS
Normal file
@ -0,0 +1 @@
|
||||
Matthew Gregan <kinetik@flim.org>
|
13
media/libcubeb/LICENSE
Normal file
13
media/libcubeb/LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright © 2011 Mozilla Foundation
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
52
media/libcubeb/Makefile.in
Normal file
52
media/libcubeb/Makefile.in
Normal file
@ -0,0 +1,52 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Matthew Gregan <kinetik@flim.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = cubeb
|
||||
|
||||
DIRS = \
|
||||
include \
|
||||
src \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
3
media/libcubeb/README
Normal file
3
media/libcubeb/README
Normal file
@ -0,0 +1,3 @@
|
||||
See INSTALL for build instructions.
|
||||
|
||||
Licensed under an ISC-style license. See LICENSE for details.
|
8
media/libcubeb/README_MOZILLA
Normal file
8
media/libcubeb/README_MOZILLA
Normal file
@ -0,0 +1,8 @@
|
||||
The source from this directory was copied from the cubeb
|
||||
git repository using the update.sh script. The only changes
|
||||
made were those applied by update.sh and the addition of
|
||||
Makefile.in build files for the Mozilla build system.
|
||||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
The git commit ID used was ddfaaf39c1a15cfb1a04ce62d6bd253737fc764a-dirty.
|
48
media/libcubeb/include/Makefile.in
Normal file
48
media/libcubeb/include/Makefile.in
Normal file
@ -0,0 +1,48 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Matthew Gregan <kinetik@flim.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
EXPORTS_NAMESPACES = cubeb
|
||||
EXPORTS_cubeb = cubeb.h cubeb-stdint.h
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
1
media/libcubeb/include/cubeb-stdint.h
Normal file
1
media/libcubeb/include/cubeb-stdint.h
Normal file
@ -0,0 +1 @@
|
||||
#include "mozilla/StdInt.h"
|
208
media/libcubeb/include/cubeb.h
Normal file
208
media/libcubeb/include/cubeb.h
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright © 2011 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#ifndef CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382
|
||||
#define CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382
|
||||
|
||||
#include <cubeb/cubeb-stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @mainpage
|
||||
|
||||
@section intro Introduction
|
||||
|
||||
This is the documentation for the <tt>libcubeb</tt> C API.
|
||||
<tt>libcubeb</tt> is a callback-based audio API library allowing the
|
||||
authoring of portable multiplatform audio playback.
|
||||
|
||||
@section example Example code
|
||||
|
||||
@code
|
||||
cubeb * app_ctx;
|
||||
cubeb_init(&app_ctx, "Example Application");
|
||||
|
||||
cubeb_stream_params params;
|
||||
params.format = CUBEB_SAMPLE_S16NE;
|
||||
params.rate = 48000;
|
||||
params.channels = 2;
|
||||
|
||||
unsigned int latency_ms = 250;
|
||||
|
||||
cubeb_stream * stm;
|
||||
cubeb_stream_init(app_ctx, &stm, "Example Stream 1", params,
|
||||
latency_ms, data_cb, state_cb, NULL);
|
||||
|
||||
cubeb_stream_start(stm);
|
||||
for (;;) {
|
||||
cubeb_get_time(stm, &ts);
|
||||
printf("time=%lu\n", ts);
|
||||
sleep(1);
|
||||
}
|
||||
cubeb_stream_stop(stm);
|
||||
|
||||
cubeb_stream_destroy(stm);
|
||||
cubeb_destroy(app_ctx);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
long data_cb(cubeb_stream * stm, void * user, void * buffer, long nframes)
|
||||
{
|
||||
short * buf = buffer;
|
||||
for (i = 0; i < nframes; ++i) {
|
||||
for (c = 0; c < params.channels; ++c) {
|
||||
buf[i][c] = 0;
|
||||
}
|
||||
}
|
||||
return nframes;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@code
|
||||
int state_cb(cubeb_stream * stm, void * user, cubeb_state state)
|
||||
{
|
||||
printf("state=%d\n", state);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
The <tt>libcubeb</tt> C API. */
|
||||
|
||||
typedef struct cubeb cubeb; /**< Opaque handle referencing the application state. */
|
||||
typedef struct cubeb_stream cubeb_stream; /**< Opaque handle referencing the stream state. */
|
||||
|
||||
/** Sample format enumeration. */
|
||||
typedef enum {
|
||||
/**< Little endian 16-bit signed PCM. */
|
||||
CUBEB_SAMPLE_S16LE,
|
||||
/**< Big endian 16-bit signed PCM. */
|
||||
CUBEB_SAMPLE_S16BE,
|
||||
/**< Little endian 32-bit IEEE floating point PCM. */
|
||||
CUBEB_SAMPLE_FLOAT32LE,
|
||||
/**< Big endian 32-bit IEEE floating point PCM. */
|
||||
CUBEB_SAMPLE_FLOAT32BE,
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
/**< Native endian 16-bit signed PCM. */
|
||||
CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16BE,
|
||||
/**< Native endian 32-bit IEEE floating point PCM. */
|
||||
CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32BE
|
||||
#else
|
||||
/**< Native endian 16-bit signed PCM. */
|
||||
CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16LE,
|
||||
/**< Native endian 32-bit IEEE floating point PCM. */
|
||||
CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32LE
|
||||
#endif
|
||||
} cubeb_sample_format;
|
||||
|
||||
/** Stream format initialization parameters. */
|
||||
typedef struct {
|
||||
cubeb_sample_format format; /**< Requested sample format. One of
|
||||
#cubeb_sample_format. */
|
||||
unsigned int rate; /**< Requested sample rate. Valid range is [1, 192000]. */
|
||||
unsigned int channels; /**< Requested channel count. Valid range is [1, 32]. */
|
||||
} cubeb_stream_params;
|
||||
|
||||
/** Stream states signaled via state_callback. */
|
||||
typedef enum {
|
||||
CUBEB_STATE_STARTED, /**< Stream started. */
|
||||
CUBEB_STATE_STOPPED, /**< Stream stopped. */
|
||||
CUBEB_STATE_DRAINED /**< Stream drained. */
|
||||
} cubeb_state;
|
||||
|
||||
/** Result code enumeration. */
|
||||
enum {
|
||||
CUBEB_OK = 0, /**< Success. */
|
||||
CUBEB_ERROR = -1, /**< Unclassified error. */
|
||||
CUBEB_ERROR_INVALID_FORMAT /**< Unsupported #cubeb_stream_params requested. */
|
||||
};
|
||||
|
||||
/** User supplied data callback.
|
||||
@param stream
|
||||
@param user_ptr
|
||||
@param buffer
|
||||
@param nframes
|
||||
@retval Number of frames written to buffer, which must equal nframes except at end of stream.
|
||||
@retval CUBEB_ERROR on error, in which case the data callback will stop
|
||||
and the stream will enter a shutdown state. */
|
||||
typedef long (* cubeb_data_callback)(cubeb_stream * stream,
|
||||
void * user_ptr,
|
||||
void * buffer,
|
||||
long nframes);
|
||||
|
||||
/** User supplied state callback.
|
||||
@param stream
|
||||
@param user_ptr
|
||||
@param state
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR */
|
||||
typedef int (* cubeb_state_callback)(cubeb_stream * stream,
|
||||
void * user_ptr,
|
||||
cubeb_state state);
|
||||
|
||||
/** Initialize an application context. This will perform any library or
|
||||
application scoped initialization.
|
||||
@param context
|
||||
@param context_name
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_init(cubeb ** context, char const * context_name);
|
||||
|
||||
/** Destroy an application context.
|
||||
@param context */
|
||||
void cubeb_destroy(cubeb * context);
|
||||
|
||||
/** Initialize a stream associated with the supplied application context.
|
||||
@param context
|
||||
@param stream
|
||||
@param stream_name
|
||||
@param stream_params
|
||||
@param latency Approximate stream latency in milliseconds. Valid range is [1, 2000].
|
||||
@param data_callback Will be called to preroll data before playback is
|
||||
started by cubeb_stream_start.
|
||||
@param state_callback
|
||||
@param user_ptr
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR
|
||||
@retval CUBEB_ERROR_INVALID_FORMAT */
|
||||
int cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
cubeb_data_callback data_callback,
|
||||
cubeb_state_callback state_callback,
|
||||
void * user_ptr);
|
||||
|
||||
/** Destroy a stream.
|
||||
@param stream */
|
||||
void cubeb_stream_destroy(cubeb_stream * stream);
|
||||
|
||||
/** Start playback.
|
||||
@param stream
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_stream_start(cubeb_stream * stream);
|
||||
|
||||
/** Stop playback.
|
||||
@param stream
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_stream_stop(cubeb_stream * stream);
|
||||
|
||||
/** Get the current stream playback position.
|
||||
@param stream
|
||||
@param position Playback position in frames.
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR */
|
||||
int cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382 */
|
58
media/libcubeb/src/Makefile.in
Normal file
58
media/libcubeb/src/Makefile.in
Normal file
@ -0,0 +1,58 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Matthew Gregan <kinetik@flim.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = cubeb
|
||||
LIBRARY_NAME = cubeb
|
||||
FORCE_STATIC_LIB= 1
|
||||
ifeq (WINNT,$(OS_TARGET))
|
||||
VISIBILITY_FLAGS =
|
||||
endif
|
||||
|
||||
ifeq (WINNT,$(OS_TARGET))
|
||||
CSRCS = \
|
||||
cubeb_winmm.c \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
433
media/libcubeb/src/cubeb_winmm.c
Normal file
433
media/libcubeb/src/cubeb_winmm.c
Normal file
@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Copyright <EFBFBD>Â<EFBFBD>© 2011 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <mmreg.h>
|
||||
#include <mmsystem.h>
|
||||
#include <process.h>
|
||||
#include <stdlib.h>
|
||||
#include "cubeb/cubeb.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define NBUFS 4
|
||||
|
||||
struct cubeb_stream_item {
|
||||
SLIST_ENTRY head;
|
||||
cubeb_stream * stream;
|
||||
};
|
||||
|
||||
struct cubeb {
|
||||
HANDLE event;
|
||||
HANDLE thread;
|
||||
int shutdown;
|
||||
PSLIST_HEADER work;
|
||||
};
|
||||
|
||||
struct cubeb_stream {
|
||||
cubeb * context;
|
||||
cubeb_stream_params params;
|
||||
cubeb_data_callback data_callback;
|
||||
cubeb_state_callback state_callback;
|
||||
void * user_ptr;
|
||||
WAVEHDR buffers[NBUFS];
|
||||
int next_buffer;
|
||||
int free_buffers;
|
||||
int shutdown;
|
||||
int draining;
|
||||
HANDLE event;
|
||||
HWAVEOUT waveout;
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
|
||||
static size_t
|
||||
bytes_per_frame(cubeb_stream_params params)
|
||||
{
|
||||
size_t bytes;
|
||||
|
||||
switch (params.format) {
|
||||
case CUBEB_SAMPLE_S16LE:
|
||||
bytes = sizeof(signed int);
|
||||
break;
|
||||
case CUBEB_SAMPLE_FLOAT32LE:
|
||||
bytes = sizeof(float);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return bytes * params.channels;
|
||||
}
|
||||
|
||||
static WAVEHDR *
|
||||
cubeb_get_next_buffer(cubeb_stream * stm)
|
||||
{
|
||||
WAVEHDR * hdr = NULL;
|
||||
|
||||
assert(stm->free_buffers > 0 && stm->free_buffers <= NBUFS);
|
||||
hdr = &stm->buffers[stm->next_buffer];
|
||||
assert(hdr->dwFlags == 0 ||
|
||||
(hdr->dwFlags & WHDR_DONE && !(hdr->dwFlags & WHDR_INQUEUE)));
|
||||
stm->next_buffer = (stm->next_buffer + 1) % NBUFS;
|
||||
stm->free_buffers -= 1;
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
static void
|
||||
cubeb_submit_buffer(cubeb_stream * stm, WAVEHDR * hdr)
|
||||
{
|
||||
long got;
|
||||
MMRESULT r;
|
||||
|
||||
got = stm->data_callback(stm, stm->user_ptr, hdr->lpData,
|
||||
hdr->dwBufferLength / bytes_per_frame(stm->params));
|
||||
if (got < 0) {
|
||||
/* XXX handle this case */
|
||||
assert(0);
|
||||
return;
|
||||
} else if ((DWORD) got < hdr->dwBufferLength / bytes_per_frame(stm->params)) {
|
||||
r = waveOutUnprepareHeader(stm->waveout, hdr, sizeof(*hdr));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
hdr->dwBufferLength = got * bytes_per_frame(stm->params);
|
||||
|
||||
r = waveOutPrepareHeader(stm->waveout, hdr, sizeof(*hdr));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
stm->draining = 1;
|
||||
}
|
||||
|
||||
assert(hdr->dwFlags & WHDR_PREPARED);
|
||||
|
||||
r = waveOutWrite(stm->waveout, hdr, sizeof(*hdr));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
}
|
||||
|
||||
static unsigned __stdcall
|
||||
cubeb_buffer_thread(void * user_ptr)
|
||||
{
|
||||
cubeb * ctx = (cubeb *) user_ptr;
|
||||
assert(ctx);
|
||||
|
||||
for (;;) {
|
||||
DWORD rv;
|
||||
struct cubeb_stream_item * item;
|
||||
|
||||
rv = WaitForSingleObject(ctx->event, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
|
||||
item = (struct cubeb_stream_item *) InterlockedPopEntrySList(ctx->work);
|
||||
while (item) {
|
||||
cubeb_stream * stm = item->stream;
|
||||
|
||||
EnterCriticalSection(&stm->lock);
|
||||
stm->free_buffers += 1;
|
||||
assert(stm->free_buffers > 0 && stm->free_buffers <= NBUFS);
|
||||
|
||||
if (stm->draining || stm->shutdown) {
|
||||
if (stm->free_buffers == NBUFS) {
|
||||
if (stm->draining) {
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
|
||||
}
|
||||
SetEvent(stm->event);
|
||||
}
|
||||
} else {
|
||||
cubeb_submit_buffer(stm, cubeb_get_next_buffer(stm));
|
||||
}
|
||||
LeaveCriticalSection(&stm->lock);
|
||||
|
||||
_aligned_free(item);
|
||||
|
||||
item = (struct cubeb_stream_item *) InterlockedPopEntrySList(ctx->work);
|
||||
}
|
||||
|
||||
if (ctx->shutdown) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void CALLBACK
|
||||
cubeb_buffer_callback(HWAVEOUT waveout, UINT msg, DWORD_PTR user_ptr, DWORD_PTR p1, DWORD_PTR p2)
|
||||
{
|
||||
cubeb_stream * stm = (cubeb_stream *) user_ptr;
|
||||
struct cubeb_stream_item * item;
|
||||
|
||||
if (msg != WOM_DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
item = _aligned_malloc(sizeof(struct cubeb_stream_item), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
assert(item);
|
||||
item->stream = stm;
|
||||
InterlockedPushEntrySList(stm->context->work, &item->head);
|
||||
|
||||
SetEvent(stm->context->event);
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_init(cubeb ** context, char const * context_name)
|
||||
{
|
||||
cubeb * ctx;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
assert(ctx);
|
||||
|
||||
ctx->work = _aligned_malloc(sizeof(*ctx->work), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
assert(ctx->work);
|
||||
InitializeSListHead(ctx->work);
|
||||
|
||||
ctx->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (!ctx->event) {
|
||||
cubeb_destroy(ctx);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
ctx->thread = (HANDLE) _beginthreadex(NULL, 64 * 1024, cubeb_buffer_thread, ctx, 0, NULL);
|
||||
if (!ctx->thread) {
|
||||
cubeb_destroy(ctx);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
*context = ctx;
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_destroy(cubeb * ctx)
|
||||
{
|
||||
DWORD rv;
|
||||
|
||||
assert(!InterlockedPopEntrySList(ctx->work));
|
||||
|
||||
if (ctx->thread) {
|
||||
ctx->shutdown = 1;
|
||||
SetEvent(ctx->event);
|
||||
rv = WaitForSingleObject(ctx->thread, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
CloseHandle(ctx->thread);
|
||||
}
|
||||
|
||||
if (ctx->event) {
|
||||
CloseHandle(ctx->event);
|
||||
}
|
||||
|
||||
_aligned_free(ctx->work);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
cubeb_data_callback data_callback,
|
||||
cubeb_state_callback state_callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
MMRESULT r;
|
||||
WAVEFORMATEXTENSIBLE wfx;
|
||||
cubeb_stream * stm;
|
||||
int i;
|
||||
size_t bufsz;
|
||||
|
||||
if (stream_params.rate < 1 || stream_params.rate > 192000 ||
|
||||
stream_params.channels < 1 || stream_params.channels > 32 ||
|
||||
latency < 1 || latency > 2000) {
|
||||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
memset(&wfx, 0, sizeof(wfx));
|
||||
if (stream_params.channels > 2) {
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
wfx.Format.cbSize = sizeof(wfx) - sizeof(wfx.Format);
|
||||
} else {
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
if (stream_params.format == CUBEB_SAMPLE_FLOAT32LE) {
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
}
|
||||
wfx.Format.cbSize = 0;
|
||||
}
|
||||
wfx.Format.nChannels = stream_params.channels;
|
||||
wfx.Format.nSamplesPerSec = stream_params.rate;
|
||||
|
||||
/* XXX fix channel mappings */
|
||||
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
|
||||
|
||||
switch (stream_params.format) {
|
||||
case CUBEB_SAMPLE_S16LE:
|
||||
wfx.Format.wBitsPerSample = 16;
|
||||
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
break;
|
||||
case CUBEB_SAMPLE_FLOAT32LE:
|
||||
wfx.Format.wBitsPerSample = 32;
|
||||
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
break;
|
||||
default:
|
||||
return CUBEB_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
wfx.Format.nBlockAlign = (wfx.Format.wBitsPerSample * wfx.Format.nChannels) / 8;
|
||||
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
|
||||
wfx.Samples.wValidBitsPerSample = 0;
|
||||
wfx.Samples.wSamplesPerBlock = 0;
|
||||
wfx.Samples.wReserved = 0;
|
||||
|
||||
stm = calloc(1, sizeof(*stm));
|
||||
assert(stm);
|
||||
|
||||
stm->context = context;
|
||||
|
||||
stm->params = stream_params;
|
||||
|
||||
stm->data_callback = data_callback;
|
||||
stm->state_callback = state_callback;
|
||||
stm->user_ptr = user_ptr;
|
||||
|
||||
bufsz = (size_t) (stm->params.rate / 1000.0 * latency * bytes_per_frame(stm->params) / NBUFS);
|
||||
if (bufsz % bytes_per_frame(stm->params) != 0) {
|
||||
bufsz += bytes_per_frame(stm->params) - (bufsz % bytes_per_frame(stm->params));
|
||||
}
|
||||
assert(bufsz % bytes_per_frame(stm->params) == 0);
|
||||
|
||||
for (i = 0; i < NBUFS; ++i) {
|
||||
stm->buffers[i].lpData = calloc(1, bufsz);
|
||||
assert(stm->buffers[i].lpData);
|
||||
stm->buffers[i].dwBufferLength = bufsz;
|
||||
stm->buffers[i].dwFlags = 0;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&stm->lock);
|
||||
|
||||
stm->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (!stm->event) {
|
||||
cubeb_stream_destroy(stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
stm->free_buffers = NBUFS;
|
||||
|
||||
/* cubeb_buffer_callback will be called during waveOutOpen, so all
|
||||
other initialization must be complete before calling it. */
|
||||
r = waveOutOpen(&stm->waveout, WAVE_MAPPER, &wfx.Format,
|
||||
(DWORD_PTR) cubeb_buffer_callback, (DWORD_PTR) stm,
|
||||
CALLBACK_FUNCTION);
|
||||
if (r != MMSYSERR_NOERROR) {
|
||||
cubeb_stream_destroy(stm);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
r = waveOutPause(stm->waveout);
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
for (i = 0; i < NBUFS; ++i) {
|
||||
WAVEHDR * hdr = cubeb_get_next_buffer(stm);
|
||||
|
||||
r = waveOutPrepareHeader(stm->waveout, hdr, sizeof(*hdr));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
cubeb_submit_buffer(stm, hdr);
|
||||
}
|
||||
|
||||
*stream = stm;
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_stream_destroy(cubeb_stream * stm)
|
||||
{
|
||||
MMRESULT r;
|
||||
DWORD rv;
|
||||
int i;
|
||||
int enqueued;
|
||||
|
||||
if (stm->waveout) {
|
||||
EnterCriticalSection(&stm->lock);
|
||||
stm->shutdown = 1;
|
||||
|
||||
r = waveOutReset(stm->waveout);
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
enqueued = NBUFS - stm->free_buffers;
|
||||
LeaveCriticalSection(&stm->lock);
|
||||
|
||||
/* wait for all blocks to complete */
|
||||
if (enqueued > 0) {
|
||||
rv = WaitForSingleObject(stm->event, INFINITE);
|
||||
assert(rv == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
for (i = 0; i < NBUFS; ++i) {
|
||||
r = waveOutUnprepareHeader(stm->waveout, &stm->buffers[i], sizeof(stm->buffers[i]));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
}
|
||||
|
||||
r = waveOutClose(stm->waveout);
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
}
|
||||
|
||||
if (stm->event) {
|
||||
CloseHandle(stm->event);
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&stm->lock);
|
||||
|
||||
for (i = 0; i < NBUFS; ++i) {
|
||||
free(stm->buffers[i].lpData);
|
||||
}
|
||||
|
||||
free(stm);
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_stream_start(cubeb_stream * stm)
|
||||
{
|
||||
MMRESULT r;
|
||||
|
||||
r = waveOutRestart(stm->waveout);
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_stream_stop(cubeb_stream * stm)
|
||||
{
|
||||
MMRESULT r;
|
||||
|
||||
r = waveOutPause(stm->waveout);
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
|
||||
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
cubeb_stream_get_position(cubeb_stream * stm, uint64_t * position)
|
||||
{
|
||||
MMRESULT r;
|
||||
MMTIME time;
|
||||
|
||||
time.wType = TIME_SAMPLES;
|
||||
r = waveOutGetPosition(stm->waveout, &time, sizeof(time));
|
||||
assert(r == MMSYSERR_NOERROR);
|
||||
assert(time.wType == TIME_SAMPLES);
|
||||
|
||||
*position = time.u.sample;
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
27
media/libcubeb/update.sh
Normal file
27
media/libcubeb/update.sh
Normal file
@ -0,0 +1,27 @@
|
||||
# Usage: sh update.sh <upstream_src_directory>
|
||||
set -e
|
||||
|
||||
cp $1/include/cubeb/cubeb.h include
|
||||
cp $1/src/cubeb_alsa.c src
|
||||
cp $1/src/cubeb_winmm.c src
|
||||
cp $1/src/cubeb_audiounit.c src
|
||||
cp $1/LICENSE .
|
||||
cp $1/README .
|
||||
cp $1/AUTHORS .
|
||||
if [ -d $1/.git ]; then
|
||||
rev=$(cd $1 && git rev-parse --verify HEAD)
|
||||
dirty=$(cd $1 && git diff-index --name-only HEAD)
|
||||
fi
|
||||
|
||||
if [ -n "$rev" ]; then
|
||||
version=$rev
|
||||
if [ -n "$dirty" ]; then
|
||||
version=$version-dirty
|
||||
echo "WARNING: updating from a dirty git repository."
|
||||
fi
|
||||
sed -i.bak -e "/The git commit ID used was/ s/[0-9a-f]\+\(-dirty\)\?\./$version./" README_MOZILLA
|
||||
rm README_MOZILLA.bak
|
||||
else
|
||||
echo "Remember to update README_MOZILLA with the version details."
|
||||
fi
|
||||
|
@ -132,6 +132,7 @@
|
||||
<li><a href="about:license#jpnic">Japan Network Information Center License</a></li>
|
||||
<li><a href="about:license#jemalloc">jemalloc License</a></li>
|
||||
<li><a href="about:license#jquery">jQuery License</a></li>
|
||||
<li><a href="about:license#libcubeb">libcubeb License</a></li>
|
||||
<li><a href="about:license#libevent">libevent License</a></li>
|
||||
<li><a href="about:license#libffi">libffi License</a></li>
|
||||
<li><a href="about:license#libnestegg">libnestegg License</a></li>
|
||||
@ -2936,6 +2937,30 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
<hr>
|
||||
|
||||
<h1><a name="libcubeb"></a>libcubeb License</h1>
|
||||
|
||||
<p class="correctme">This license applies to files in the directory
|
||||
<span class="path">media/libcubeb</span>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Copyright © 2011 Mozilla Foundation
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1><a name="libevent"></a>libevent License</h1>
|
||||
|
||||
<p>This license applies to files in the directory
|
||||
|
@ -1584,6 +1584,14 @@ if [ "$MOZ_WAVE" ]; then
|
||||
"
|
||||
fi
|
||||
|
||||
if [ "$MOZ_CUBEB" ]; then
|
||||
add_makefiles "
|
||||
media/libcubeb/Makefile
|
||||
media/libcubeb/include/Makefile
|
||||
media/libcubeb/src/Makefile
|
||||
"
|
||||
fi
|
||||
|
||||
if [ "$MOZ_SYDNEYAUDIO" ]; then
|
||||
add_makefiles "
|
||||
media/libsydneyaudio/Makefile
|
||||
|
@ -154,6 +154,12 @@ tier_platform_dirs += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_CUBEB
|
||||
tier_platform_dirs += \
|
||||
media/libcubeb \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifndef MOZ_NATIVE_PNG
|
||||
tier_platform_dirs += media/libpng
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user