ref: 57832441cc501b894f9528f949540d7ccf3704fd
parent: 2b249750bc49554358916d83392a4d2e006f5b3a
author: Gregory Maxwell <greg@xiph.org>
date: Sat May 26 22:54:50 EDT 2012
Win32 portability fixes.
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,1 +1,5 @@
Gregory Maxwell (greg@xiph.org)
+Jean-Marc Valin - Original opusdec implementation / Resampler
+Thorvald Natvig - Resampler
+Michael Smith - Ogginfo (basis of opusinfo)
+John Edwards - Windows audio output
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@
INCLUDES = -I$(top_srcdir)/src
-AM_CFLAGS = $(OGG_CFLAGS) $(Opus_CFLAGS) -DOPUSTOOLS -D_FORTIFY_SOURCE=2 -DHAVE_GETOPT_H -DEXPORT= -DRANDOM_PREFIX=opustools -DOUTSIDE_SPEEX -DFLOATING_POINT
+AM_CFLAGS = $(OGG_CFLAGS) $(Opus_CFLAGS) -DOPUSTOOLS -D_FORTIFY_SOURCE=2 -DHAVE_GETOPT_H -DSPX_RESAMPLE_EXPORT= -DRANDOM_PREFIX=opustools -DOUTSIDE_SPEEX -DFLOATING_POINT
bin_PROGRAMS = opusenc opusdec opusinfo
--- a/Makefile.unix
+++ b/Makefile.unix
@@ -1,5 +1,5 @@
#CC=gcc
-CFLAGS:=-DPACKAGE='"opus-tools"' -DVERSION='"0.1.0"' -DOPUSTOOLS -DHAVE_SYS_SOUNDCARD_H -O2 -g -c -Wall -Wextra -DHAVE_GETOPT_H -DEXPORT= -DRANDOM_PREFIX=opustools -DOUTSIDE_SPEEX -DFLOATING_POINT $(CFLAGS)
+CFLAGS:=-DPACKAGE='"opus-tools"' -DVERSION='"0.1.0"' -DOPUSTOOLS -DHAVE_SYS_SOUNDCARD_H -O2 -g -c -Wall -Wextra -DHAVE_GETOPT_H -DSPX_RESAMPLE_EXPORT= -DRANDOM_PREFIX=opustools -DOUTSIDE_SPEEX -DFLOATING_POINT $(CFLAGS)
INCLUDES=-I../opus/include
all: opusenc opusdec opusinfo
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,8 @@
fi
AC_SUBST([LIBM])
+AC_CHECK_LIB(winmm, main)
+
AC_DEFINE_UNQUOTED(PACKAGE, "${OPUSTOOLS_VERSION}", [Package name])
AC_DEFINE_UNQUOTED(VERSION, "${OPUSTOOLS_VERSION}", [Package version])
AC_DEFINE_UNQUOTED(OPUSTOOLS_MAJOR_VERSION, ${OPUSTOOLS_MAJOR_VERSION}, [Version major])
--- a/src/audio-in.c
+++ b/src/audio-in.c
@@ -37,7 +37,16 @@
#include <string.h>
#include <sys/types.h>
#include <math.h>
-#include <alloca.h>
+
+#ifdef WIN32
+# include <malloc.h>
+#else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# include <stdlib.h>
+# endif
+#endif
#ifdef ENABLE_NLS
#include <libintl.h>
--- a/src/diag_range.c
+++ b/src/diag_range.c
@@ -31,6 +31,14 @@
# include "config.h"
#endif
+#ifdef _WIN32
+#define I64FORMAT "I64d"
+#define I64uFORMAT "I64u"
+#else
+#define I64FORMAT "lld"
+#define I64uFORMAT "llu"
+#endif
+
#include <stdio.h>
#include <opus.h>
#include "diag_range.h"
@@ -230,7 +238,7 @@
mode_strings[((((subpkt[0]>>3)+48)&92)+4)>>5],
bw_strings[opus_packet_get_bandwidth(subpkt)-OPUS_BANDWIDTH_NARROWBAND],
subpkt[0]&4?'S':'M',opus_packet_get_samples_per_frame(subpkt,48000));
- fprintf(frange,", %llu]%s",(unsigned long long)rngs[i],i+1==nb_streams?"\n":", ");
+ fprintf(frange,", %" I64uFORMAT "]%s",(unsigned long long)rngs[i],i+1==nb_streams?"\n":", ");
parsed_size-=payload_offset;
subpkt+=payload_offset;
}
--- a/src/info_opus.c
+++ b/src/info_opus.c
@@ -43,7 +43,7 @@
#include "info_opus.h"
/* From libopus, src/opus_decode.c */
-static int packet_get_samples_per_frame(const unsigned char *data, int32_t Fs)
+static int packet_get_samples_per_frame(const unsigned char *data, ogg_int32_t Fs)
{
int audiosize;
if (data[0]&0x80)
@@ -64,7 +64,7 @@
}
/* From libopus, src/opus_decode.c */
-static int packet_get_nb_frames(const unsigned char packet[], int32_t len)
+static int packet_get_nb_frames(const unsigned char packet[], ogg_int32_t len)
{
int count;
if (len<1)
@@ -99,7 +99,7 @@
inf->last_eos = ogg_page_eos(page);
while(1) {
- int32_t spp;
+ ogg_int32_t spp;
res = ogg_stream_packetout(&stream->os, &packet);
if(res < 0) {
oi_warn(_("WARNING: discontinuity in stream (%d)\n"), stream->num);
--- a/src/opusdec.c
+++ b/src/opusdec.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2002-2007 Jean-Marc Valin
Copyright (c) 2008 CSIRO
- Copyright (c) 2007-2009 Xiph.Org Foundation
+ Copyright (c) 2007-2012 Xiph.Org Foundation
File: opusdec.c
Redistribution and use in source and binary forms, with or without
@@ -57,8 +57,10 @@
#endif
#include <math.h>
-#ifdef __MINGW32__
-#include "wave_out.c"
+#ifdef _WIN32
+#define I64FORMAT "I64d"
+#else
+#define I64FORMAT "lld"
#endif
#if defined HAVE_SYS_SOUNDCARD_H || defined HAVE_MACHINE_SOUNDCARD_H || HAVE_SOUNDCARD_H
@@ -193,7 +195,7 @@
static void print_comments(char *comments, int length)
{
char *c=comments;
- int len, i, nb_fields;
+ int len, i, nb_fields, err=0;
if (length<(8+4+4))
{
@@ -214,7 +216,7 @@
fprintf (stderr, "Invalid/corrupted comments\n");
return;
}
- fwrite(c, 1, len, stderr);
+ err&=fwrite(c, 1, len, stderr)!=(unsigned)len;
c+=len;
fprintf (stderr, "\n");
/*The -16 check above makes sure we can read this.*/
@@ -241,7 +243,7 @@
fprintf (stderr, "Invalid/corrupted comments\n");
return;
}
- fwrite(c, 1, len, stderr);
+ err&=fwrite(c, 1, len, stderr)!=(unsigned)len;
c+=len;
length-=len;
fprintf (stderr, "\n");
@@ -492,7 +494,14 @@
if(maxout>0)
{
- ret=fwrite(out, 2*channels, out_len<maxout?out_len:maxout, fout);
+#if defined WIN32 || defined _WIN32
+ if(!file){
+ ret=WIN_Play_Samples (out, sizeof(short) * channels * (out_len<maxout?out_len:maxout));
+ if(ret>0)ret/=sizeof(short)*channels;
+ else fprintf(stderr, "Error playing audio.\n");
+ }else
+#endif
+ ret=fwrite(out, 2*channels, out_len<maxout?out_len:maxout, fout);
sampout+=ret;
maxout-=ret;
}
@@ -701,7 +710,7 @@
eos = 0;
total_links++;
} else {
- fprintf(stderr,"Warning: ignoring opus stream %lld\n",(long long)os.serialno);
+ fprintf(stderr,"Warning: ignoring opus stream %" I64FORMAT "\n",(long long)os.serialno);
}
}
if (!has_opus_stream || os.serialno != opus_serialno)
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -44,6 +44,12 @@
#define snprintf _snprintf
#endif
+#ifdef _WIN32
+#define I64FORMAT "I64d"
+#else
+#define I64FORMAT "lld"
+#endif
+
#include <opus.h>
#include <opus_multistream.h>
#include <ogg/ogg.h>
@@ -154,9 +160,9 @@
seconds-=hours*3600.;
minutes=seconds/60;
seconds-=minutes*60.;
- if(hours)fprintf(stderr," %lld hour%s%s",hours,hours>1?"s":"",
+ if(hours)fprintf(stderr," %" I64FORMAT " hour%s%s",hours,hours>1?"s":"",
minutes&&!(seconds>0)?" and":"");
- if(minutes)fprintf(stderr,"%s%lld minute%s%s",hours?", ":" ",minutes,
+ if(minutes)fprintf(stderr,"%s%" I64FORMAT " minute%s%s",hours?", ":" ",minutes,
minutes>1?"s":"",!hours&&seconds>0?" and":seconds>0?", and":"");
if(seconds>0)fprintf(stderr," %0.4g second%s",seconds,seconds!=1?"s":"");
}
@@ -903,7 +909,7 @@
fprintf(stderr,"\n Runtime:");
print_time(wall_time);
fprintf(stderr,"\n (%0.4gx realtime)\n",coded_seconds/wall_time);
- fprintf(stderr," Wrote: %lld bytes, %d packets, %lld pages\n",bytes_written,id+1,pages_out);
+ fprintf(stderr," Wrote: %" I64FORMAT " bytes, %d packets, %" I64FORMAT " pages\n",bytes_written,id+1,pages_out);
fprintf(stderr," Bitrate: %0.6gkbit/s (without overhead)\n",
total_bytes*8.0/(coded_seconds)/1000.0);
fprintf(stderr," Rate range: %0.6gkbit/s to %0.6gkbit/s\n (%d to %d bytes per packet)\n",
--- a/src/opusinfo.c
+++ b/src/opusinfo.c
@@ -571,7 +571,8 @@
printf (_(" by the Xiph.Org Foundation (http://www.xiph.org/)\n\n"));
printf(_("(c) 2003-2005 Michael Smith <msmith@xiph.org>\n"
"(c) 2012 Gregory Maxwell <greg@xiph.org>\n\n"
- "Opusinfo is a version of ogginfo from the vorbis-tools package which only works with opus.\n\n"
+ "Opusinfo is a fork of ogginfo from the vorbis-tools package\n"
+ "which has been cut down to only support opus file.\n\n"
"Usage: opusinfo [flags] file1.opua [file2.opua ... fileN.opus]\n"
"Flags supported:\n"
"\t-h Show this help message\n"
--- a/src/resample.c
+++ b/src/resample.c
@@ -721,12 +721,12 @@
}
-EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
+SPX_RESAMPLE_EXPORT SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
{
return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err);
}
-EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
+SPX_RESAMPLE_EXPORT SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err)
{
spx_uint32_t i;
SpeexResamplerState *st;
@@ -785,7 +785,7 @@
return st;
}
-EXPORT void speex_resampler_destroy(SpeexResamplerState *st)
+SPX_RESAMPLE_EXPORT void speex_resampler_destroy(SpeexResamplerState *st)
{
speex_free(st->mem);
speex_free(st->sinc_table);
@@ -842,9 +842,9 @@
}
#ifdef FIXED_POINT
-EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
#else
-EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
#endif
{
int j;
@@ -883,9 +883,9 @@
}
#ifdef FIXED_POINT
-EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
#else
-EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
#endif
{
int j;
@@ -956,7 +956,7 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len)
{
spx_uint32_t i;
int istride_save, ostride_save;
@@ -977,7 +977,7 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
+SPX_RESAMPLE_EXPORT int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
{
spx_uint32_t i;
int istride_save, ostride_save;
@@ -998,18 +998,18 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
+SPX_RESAMPLE_EXPORT int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate)
{
return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate);
}
-EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
+SPX_RESAMPLE_EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate)
{
*in_rate = st->in_rate;
*out_rate = st->out_rate;
}
-EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
+SPX_RESAMPLE_EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
{
spx_uint32_t fact;
spx_uint32_t old_den;
@@ -1048,13 +1048,13 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
+SPX_RESAMPLE_EXPORT void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den)
{
*ratio_num = st->num_rate;
*ratio_den = st->den_rate;
}
-EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
+SPX_RESAMPLE_EXPORT int speex_resampler_set_quality(SpeexResamplerState *st, int quality)
{
if (quality > 10 || quality < 0)
return RESAMPLER_ERR_INVALID_ARG;
@@ -1066,42 +1066,42 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
+SPX_RESAMPLE_EXPORT void speex_resampler_get_quality(SpeexResamplerState *st, int *quality)
{
*quality = st->quality;
}
-EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
+SPX_RESAMPLE_EXPORT void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride)
{
st->in_stride = stride;
}
-EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
+SPX_RESAMPLE_EXPORT void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride)
{
*stride = st->in_stride;
}
-EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
+SPX_RESAMPLE_EXPORT void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride)
{
st->out_stride = stride;
}
-EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
+SPX_RESAMPLE_EXPORT void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride)
{
*stride = st->out_stride;
}
-EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st)
+SPX_RESAMPLE_EXPORT int speex_resampler_get_input_latency(SpeexResamplerState *st)
{
return st->filt_len / 2;
}
-EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st)
+SPX_RESAMPLE_EXPORT int speex_resampler_get_output_latency(SpeexResamplerState *st)
{
return ((st->filt_len / 2) * st->den_rate + (st->num_rate >> 1)) / st->num_rate;
}
-EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st)
+SPX_RESAMPLE_EXPORT int speex_resampler_skip_zeros(SpeexResamplerState *st)
{
spx_uint32_t i;
for (i=0;i<st->nb_channels;i++)
@@ -1109,7 +1109,7 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st)
+SPX_RESAMPLE_EXPORT int speex_resampler_reset_mem(SpeexResamplerState *st)
{
spx_uint32_t i;
for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
@@ -1117,7 +1117,7 @@
return RESAMPLER_ERR_SUCCESS;
}
-EXPORT const char *speex_resampler_strerror(int err)
+SPX_RESAMPLE_EXPORT const char *speex_resampler_strerror(int err)
{
switch (err)
{
--- a/src/wave_out.c
+++ b/src/wave_out.c
@@ -1,220 +1,223 @@
-/* Copyright (c) 2002, John Edwards
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Xiph.org Foundation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-/* Set TABS = 4 */
-/********************************************************************
-
- function: To provide playback of 16 bit PCM wave data in Win32
- environments from decoded compressed files.
-
- ********************************************************************/
-
-#if defined WIN32 || defined _WIN32
-
-#include <string.h>
-#include <errno.h>
-#include "wave_out.h"
-
-#define MAXWAVESIZE 4294967040LU
-#define MAX_WAVEBLOCKS 32
-
-// This is modified for USE_WIN_AUDIO - ONLY 2002-02-27
-
-
-static CRITICAL_SECTION cs;
-static HWAVEOUT dev = NULL;
-static int ScheduledBlocks = 0;
-static int PlayedWaveHeadersCount = 0; // free index
-static WAVEHDR* PlayedWaveHeaders [MAX_WAVEBLOCKS];
-
-static int
-Box ( const char* msg )
-{
- MessageBox ( NULL, msg, " "VERSION_STRING": Error Message . . .", MB_OK | MB_ICONEXCLAMATION );
- return -1;
-}
-
-
-/*
- * This function registers already played WAVE chunks. Freeing is done by free_memory(),
- */
-
-static void CALLBACK
-wave_callback ( HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
-{
- if ( uMsg == WOM_DONE ) {
- EnterCriticalSection ( &cs );
- PlayedWaveHeaders [PlayedWaveHeadersCount++] = (WAVEHDR*) dwParam1;
- LeaveCriticalSection ( &cs );
- }
-}
-
-
-static void
-free_memory ( void )
-{
- WAVEHDR* wh;
- HGLOBAL hg;
-
- EnterCriticalSection ( &cs );
- wh = PlayedWaveHeaders [--PlayedWaveHeadersCount];
- ScheduledBlocks--; // decrease the number of USED blocks
- LeaveCriticalSection ( &cs );
-
- waveOutUnprepareHeader ( dev, wh, sizeof (WAVEHDR) );
-
- hg = GlobalHandle ( wh -> lpData ); // Deallocate the buffer memory
- GlobalUnlock (hg);
- GlobalFree (hg);
-
- hg = GlobalHandle ( wh ); // Deallocate the header memory
- GlobalUnlock (hg);
- GlobalFree (hg);
-}
-
-
-Int
-Set_WIN_Params ( FILE_T dummyFile ,
- Ldouble SampleFreq,
- Uint BitsPerSample,
- Uint Channels )
-{
- WAVEFORMATEX outFormat;
- UINT deviceID = WAVE_MAPPER;
-
- (void) dummyFile;
-
- if ( waveOutGetNumDevs () == 0 )
- return Box ( "No audio device present." );
-
- outFormat.wFormatTag = WAVE_FORMAT_PCM;
- outFormat.wBitsPerSample = BitsPerSample;
- outFormat.nChannels = Channels;
- outFormat.nSamplesPerSec = (unsigned long)(SampleFreq + 0.5);
- outFormat.nBlockAlign = (outFormat.wBitsPerSample + 7) / 8 * outFormat.nChannels;
- outFormat.nAvgBytesPerSec = outFormat.nSamplesPerSec * outFormat.nBlockAlign;
-
- switch ( waveOutOpen ( &dev, deviceID, &outFormat, (DWORD)wave_callback, 0, CALLBACK_FUNCTION ) )
- {
- case MMSYSERR_ALLOCATED: return Box ( "Device is already open." );
- case MMSYSERR_BADDEVICEID: return Box ( "The specified device is out of range." );
- case MMSYSERR_NODRIVER: return Box ( "There is no audio driver in this system." );
- case MMSYSERR_NOMEM: return Box ( "Unable to allocate sound memory." );
- case WAVERR_BADFORMAT: return Box ( "This audio format is not supported." );
- case WAVERR_SYNC: return Box ( "The device is synchronous." );
- default: return Box ( "Unknown media error." );
- case MMSYSERR_NOERROR: break;
- }
-
- waveOutReset ( dev );
- InitializeCriticalSection ( &cs );
- SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS );
- return 0;
-}
-
-
-int
-WIN_Play_Samples ( const void* data, size_t len )
-{
- HGLOBAL hg;
- HGLOBAL hg2;
- LPWAVEHDR wh;
- void* allocptr;
-
- do {
- while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
- free_memory ();
-
- if ( ScheduledBlocks < sizeof(PlayedWaveHeaders)/sizeof(*PlayedWaveHeaders) ) // wait for a free block ...
- break;
- Sleep (26);
- } while (1);
-
- if ( (hg2 = GlobalAlloc ( GMEM_MOVEABLE, len )) == NULL ) // allocate some memory for a copy of the buffer
- return Box ( "GlobalAlloc failed." );
-
- allocptr = GlobalLock (hg2);
- CopyMemory ( allocptr, data, len ); // Here we can call any modification output functions we want....
-
- if ( (hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR))) == NULL ) // now make a header and WRITE IT!
- return -1;
-
- wh = GlobalLock (hg);
- wh -> dwBufferLength = len;
- wh -> lpData = allocptr;
-
- if ( waveOutPrepareHeader ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
- GlobalUnlock (hg);
- GlobalFree (hg);
- return -1;
- }
-
- if ( waveOutWrite ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
- GlobalUnlock (hg);
- GlobalFree (hg);
- return -1;
- }
-
- EnterCriticalSection ( &cs );
- ScheduledBlocks++;
- LeaveCriticalSection ( &cs );
-
- return len;
-}
-
-
-int
-WIN_Audio_close ( void )
-{
- if ( dev != NULL ) {
-
- while ( ScheduledBlocks > 0 ) {
- Sleep (ScheduledBlocks);
- while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
- free_memory ();
- }
-
- waveOutReset (dev); // reset the device
- waveOutClose (dev); // close the device
- dev = NULL;
- }
-
- DeleteCriticalSection ( &cs );
- ScheduledBlocks = 0;
- return 0;
-}
-
-#endif
-
-/* end of wave_out.c */
+/* Copyright (c) 2002, John Edwards
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Set TABS = 4 */
+/********************************************************************
+
+ function: To provide playback of 16 bit PCM wave data in Win32
+ environments from decoded compressed files.
+
+ ********************************************************************/
+
+#if defined WIN32 || defined _WIN32
+
+#include <string.h>
+#include <errno.h>
+#include "wave_out.h"
+
+#define MAXWAVESIZE 4294967040LU
+#define MAX_WAVEBLOCKS 32
+
+// This is modified for USE_WIN_AUDIO - ONLY 2002-02-27
+
+
+static CRITICAL_SECTION cs;
+static HWAVEOUT dev = NULL;
+static unsigned ScheduledBlocks = 0;
+static int PlayedWaveHeadersCount = 0; // free index
+static WAVEHDR* PlayedWaveHeaders [MAX_WAVEBLOCKS];
+
+static int
+Box ( const char* msg )
+{
+ MessageBox ( NULL, msg, " "PACKAGE" "VERSION": Error Message . . .", MB_OK | MB_ICONEXCLAMATION );
+ return -1;
+}
+
+
+/*
+ * This function registers already played WAVE chunks. Freeing is done by free_memory(),
+ */
+
+static void CALLBACK
+wave_callback ( HWAVE hWave, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
+{
+ (void) hWave;
+ (void) dwInstance;
+ (void) dwParam2;
+ if ( uMsg == WOM_DONE ) {
+ EnterCriticalSection ( &cs );
+ PlayedWaveHeaders [PlayedWaveHeadersCount++] = (WAVEHDR*) dwParam1;
+ LeaveCriticalSection ( &cs );
+ }
+}
+
+
+static void
+free_memory ( void )
+{
+ WAVEHDR* wh;
+ HGLOBAL hg;
+
+ EnterCriticalSection ( &cs );
+ wh = PlayedWaveHeaders [--PlayedWaveHeadersCount];
+ ScheduledBlocks--; // decrease the number of USED blocks
+ LeaveCriticalSection ( &cs );
+
+ waveOutUnprepareHeader ( dev, wh, sizeof (WAVEHDR) );
+
+ hg = GlobalHandle ( wh -> lpData ); // Deallocate the buffer memory
+ GlobalUnlock (hg);
+ GlobalFree (hg);
+
+ hg = GlobalHandle ( wh ); // Deallocate the header memory
+ GlobalUnlock (hg);
+ GlobalFree (hg);
+}
+
+
+Int
+Set_WIN_Params ( FILE_T dummyFile ,
+ Ldouble SampleFreq,
+ Uint BitsPerSample,
+ Uint Channels )
+{
+ WAVEFORMATEX outFormat;
+ UINT deviceID = WAVE_MAPPER;
+
+ (void) dummyFile;
+
+ if ( waveOutGetNumDevs () == 0 )
+ return Box ( "No audio device present." );
+
+ outFormat.wFormatTag = WAVE_FORMAT_PCM;
+ outFormat.wBitsPerSample = BitsPerSample;
+ outFormat.nChannels = Channels;
+ outFormat.nSamplesPerSec = (unsigned long)(SampleFreq + 0.5);
+ outFormat.nBlockAlign = (outFormat.wBitsPerSample + 7) / 8 * outFormat.nChannels;
+ outFormat.nAvgBytesPerSec = outFormat.nSamplesPerSec * outFormat.nBlockAlign;
+
+ switch ( waveOutOpen ( &dev, deviceID, &outFormat, (DWORD)wave_callback, 0, CALLBACK_FUNCTION ) )
+ {
+ case MMSYSERR_ALLOCATED: return Box ( "Device is already open." );
+ case MMSYSERR_BADDEVICEID: return Box ( "The specified device is out of range." );
+ case MMSYSERR_NODRIVER: return Box ( "There is no audio driver in this system." );
+ case MMSYSERR_NOMEM: return Box ( "Unable to allocate sound memory." );
+ case WAVERR_BADFORMAT: return Box ( "This audio format is not supported." );
+ case WAVERR_SYNC: return Box ( "The device is synchronous." );
+ default: return Box ( "Unknown media error." );
+ case MMSYSERR_NOERROR: break;
+ }
+
+ waveOutReset ( dev );
+ InitializeCriticalSection ( &cs );
+ SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS );
+ return 0;
+}
+
+
+int
+WIN_Play_Samples ( const void* data, size_t len )
+{
+ HGLOBAL hg;
+ HGLOBAL hg2;
+ LPWAVEHDR wh;
+ void* allocptr;
+
+ do {
+ while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
+ free_memory ();
+
+ if ( ScheduledBlocks < sizeof(PlayedWaveHeaders)/sizeof(*PlayedWaveHeaders) ) // wait for a free block ...
+ break;
+ Sleep (26);
+ } while (1);
+
+ if ( (hg2 = GlobalAlloc ( GMEM_MOVEABLE, len )) == NULL ) // allocate some memory for a copy of the buffer
+ return Box ( "GlobalAlloc failed." );
+
+ allocptr = GlobalLock (hg2);
+ CopyMemory ( allocptr, data, len ); // Here we can call any modification output functions we want....
+
+ if ( (hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (WAVEHDR))) == NULL ) // now make a header and WRITE IT!
+ return -1;
+
+ wh = GlobalLock (hg);
+ wh -> dwBufferLength = len;
+ wh -> lpData = allocptr;
+
+ if ( waveOutPrepareHeader ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
+ GlobalUnlock (hg);
+ GlobalFree (hg);
+ return -1;
+ }
+
+ if ( waveOutWrite ( dev, wh, sizeof (WAVEHDR)) != MMSYSERR_NOERROR ) {
+ GlobalUnlock (hg);
+ GlobalFree (hg);
+ return -1;
+ }
+
+ EnterCriticalSection ( &cs );
+ ScheduledBlocks++;
+ LeaveCriticalSection ( &cs );
+
+ return len;
+}
+
+
+int
+WIN_Audio_close ( void )
+{
+ if ( dev != NULL ) {
+
+ while ( ScheduledBlocks > 0 ) {
+ Sleep (ScheduledBlocks);
+ while ( PlayedWaveHeadersCount > 0 ) // free used blocks ...
+ free_memory ();
+ }
+
+ waveOutReset (dev); // reset the device
+ waveOutClose (dev); // close the device
+ dev = NULL;
+ }
+
+ DeleteCriticalSection ( &cs );
+ ScheduledBlocks = 0;
+ return 0;
+}
+
+#endif
+
+/* end of wave_out.c */
--- a/src/wave_out.h
+++ b/src/wave_out.h
@@ -39,20 +39,9 @@
#include <mmsystem.h>
#endif
-#define VERSION_STRING "\n 0.11.4\n"
-
-#define Cdecl __cdecl
-#define __attribute__(x)
-#define sleep(__sec) Sleep ((__sec) * 1000)
-#define inline __inline
-#define restrict
-
//// constants /////////////////////////////////////////////////////
-#define CD_SAMPLE_FREQ 44.1e3
#define SAMPLE_SIZE 16
-#define SAMPLE_SIZE_STRING ""
-#define WINAUDIO_FD ((FILE_T)-128)
#define FILE_T FILE*
#define INVALID_FILEDESC NULL