Ticket #398: Initial support for Secret Rabbit Code (aka libsamplerate) sample rate conversionl library

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1493 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjmedia/build/Makefile b/pjmedia/build/Makefile
index 11ffdc9..fd73580 100644
--- a/pjmedia/build/Makefile
+++ b/pjmedia/build/Makefile
@@ -45,7 +45,7 @@
 			echo_suppress.o endpoint.o errno.o \
 			g711.o jbuf.o master_port.o mem_capture.o mem_player.o \
 			null_port.o plc_common.o port.o splitcomb.o \
-			resample_resample.o \
+			resample_resample.o resample_libsamplerate.o \
 			resample_port.o rtcp.o rtp.o sdp.o sdp_cmp.o sdp_neg.o \
 			session.o silencedet.o sound_port.o stream.o \
 			tonegen.o transport_ice.o transport_udp.o \
diff --git a/pjmedia/build/pjmedia.dsp b/pjmedia/build/pjmedia.dsp
index 801b96a..0a59d37 100644
--- a/pjmedia/build/pjmedia.dsp
+++ b/pjmedia/build/pjmedia.dsp
@@ -181,6 +181,10 @@
 # End Source File

 # Begin Source File

 

+SOURCE=..\src\pjmedia\resample_libsamplerate.c

+# End Source File

+# Begin Source File

+

 SOURCE=..\src\pjmedia\resample_port.c

 # End Source File

 # Begin Source File

diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index f438f18..cc6695c 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -127,54 +127,86 @@
 
 
 /*
- * **   THIS MACRO IS DEPRECATED in 0.6.   **
- * ** See libresample for configuring this **
+ * Warn about obsolete macros.
  *
- * Include small filter table in resample.
- * This adds about 9KB in rdata.
+ * PJMEDIA_HAS_SMALL_FILTER has been deprecated in 0.7.
  */
-/*
-#ifndef PJMEDIA_HAS_SMALL_FILTER
-#   define PJMEDIA_HAS_SMALL_FILTER	    1
+#if defined(PJMEDIA_HAS_SMALL_FILTER)
+#   ifdef _MSC_VER
+#	pragma message("Warning: PJMEDIA_HAS_SMALL_FILTER macro is deprecated"\
+		       " and has no effect")
+#   else
+#	warning "PJMEDIA_HAS_SMALL_FILTER macro is deprecated and has no effect"
+#   endif
 #endif
-*/
+
 
 /*
- * **   THIS MACRO IS DEPRECATED in 0.6.   **
- * ** See libresample for configuring this **
+ * Warn about obsolete macros.
  *
- * Include large filter table in resample.
- * This adds about 32KB in rdata.
+ * PJMEDIA_HAS_LARGE_FILTER has been deprecated in 0.7.
  */
-/*
-#ifndef PJMEDIA_HAS_LARGE_FILTER
-#   define PJMEDIA_HAS_LARGE_FILTER	    1
+#if defined(PJMEDIA_HAS_LARGE_FILTER)
+#   ifdef _MSC_VER
+#	pragma message("Warning: PJMEDIA_HAS_LARGE_FILTER macro is deprecated"\
+		       " and has no effect")
+#   else
+#	warning "PJMEDIA_HAS_LARGE_FILTER macro is deprecated"
+#   endif
 #endif
-*/
+
+
+/*
+ * These macros are obsolete in 0.7.1 so it will trigger compilation error.
+ * Please use PJMEDIA_RESAMPLE_IMP to select the resample implementation
+ * to use.
+ */
+#ifdef PJMEDIA_HAS_LIBRESAMPLE
+#   error "PJMEDIA_HAS_LIBRESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE'"
+#endif
+
+#ifdef PJMEDIA_HAS_SPEEX_RESAMPLE
+#   error "PJMEDIA_HAS_SPEEX_RESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_SPEEX'"
+#endif
+
+
+/*
+ * Sample rate conversion backends.
+ * Select one of these backends in PJMEDIA_RESAMPLE_IMP.
+ */
+#define PJMEDIA_RESAMPLE_NONE		    1	/**< No resampling.	    */
+#define PJMEDIA_RESAMPLE_LIBRESAMPLE	    2	/**< Sample rate conversion 
+						     using libresample.  */
+#define PJMEDIA_RESAMPLE_SPEEX		    3	/**< Sample rate conversion 
+						     using Speex. */
+#define PJMEDIA_RESAMPLE_LIBSAMPLERATE	    4	/**< Sample rate conversion 
+						     using libsamplerate 
+						     (a.k.a Secret Rabbit Code)
+						 */
 
 /**
- * Specify whether libresample should be used for the sampling
- * rate conversion. This macro and PJMEDIA_HAS_SPEEX_RESAMPLE
- * are mutually exclusive. 
+ * Select which resample implementation to use. Currently pjmedia supports:
+ *  - #PJMEDIA_RESAMPLE_LIBRESAMPLE, to use libresample-1.7, this is the default
+ *    implementation to be used.
+ *  - #PJMEDIA_RESAMPLE_LIBSAMPLERATE, to use libsamplerate implementation
+ *    (a.k.a. Secret Rabbit Code).
+ *  - #PJMEDIA_RESAMPLE_SPEEX, to use experimental sample rate conversion in
+ *    Speex library.
+ *  - #PJMEDIA_RESAMPLE_NONE, to disable sample rate conversion. Any calls to
+ *    resample function will return error.
  *
- * Default: 1 (Yes)
+ * Default is PJMEDIA_RESAMPLE_LIBRESAMPLE
  */
-#ifndef PJMEDIA_HAS_LIBRESAMPLE
-#   define PJMEDIA_HAS_LIBRESAMPLE	    1
+#ifndef PJMEDIA_RESAMPLE_IMP
+#   define PJMEDIA_RESAMPLE_IMP		    PJMEDIA_RESAMPLE_LIBRESAMPLE
 #endif
 
 
 /**
- * Specify whether Speex sample rate convertor should be used for the
- * sampling rate conversion. This macro and PJMEDIA_HAS_LIBRESAMPLE
- * are mutually exclusive.
- *
- * Default: 0
+ * Specify whether libsamplerate, when used, should be linked statically
+ * into the application. This option is only useful for Visual Studio
+ * projects, and when this static linking is enabled
  */
-#ifndef PJMEDIA_HAS_SPEEX_RESAMPLE
-#   define PJMEDIA_HAS_SPEEX_RESAMPLE	    0
-#endif
-
 
 
 /**
diff --git a/pjmedia/src/pjmedia/resample_libsamplerate.c b/pjmedia/src/pjmedia/resample_libsamplerate.c
new file mode 100644
index 0000000..9bca5e1
--- /dev/null
+++ b/pjmedia/src/pjmedia/resample_libsamplerate.c
@@ -0,0 +1,206 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia/resample.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/log.h>
+#include <pj/pool.h>
+
+/*
+ * HOW TO ACTIVATE LIBSAMPLERATE (a.k.a SRC/Secret Rabbit Code) AS
+ * PJMEDIA'S SAMPLE RATE CONVERSION BACKEND
+ *
+ * See README.txt in third_party/samplerate directory.
+ */
+
+
+#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE
+
+#include "../../third_party/libsamplerate/src/samplerate.h"
+
+#define THIS_FILE   "resample_libsamplerate.c"
+
+#if defined(_MSC_VER)
+#   ifdef _DEBUG
+#	pragma comment( lib, "../../third_party/lib/libsamplerate-i386-win32-vc-debug.lib")
+#   else
+#	pragma comment( lib, "../../third_party/lib/libsamplerate-i386-win32-vc-release.lib")
+#   endif
+#endif
+
+
+struct pjmedia_resample
+{
+    SRC_STATE	*state;
+    unsigned	 in_samples;
+    unsigned	 out_samples;
+    float	*frame_in, *frame_out;
+    unsigned	 in_extra, out_extra;
+    double	 ratio;
+};
+
+
+PJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,
+					     pj_bool_t high_quality,
+					     pj_bool_t large_filter,
+					     unsigned channel_count,
+					     unsigned rate_in,
+					     unsigned rate_out,
+					     unsigned samples_per_frame,
+					     pjmedia_resample **p_resample)
+{
+    pjmedia_resample *resample;
+    int type, err;
+
+    PJ_ASSERT_RETURN(pool && p_resample && rate_in &&
+		     rate_out && samples_per_frame, PJ_EINVAL);
+
+    resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample);
+    PJ_ASSERT_RETURN(resample, PJ_ENOMEM);
+
+    /* Select conversion type */
+    if (high_quality) {
+	type = large_filter ? SRC_SINC_BEST_QUALITY : SRC_SINC_MEDIUM_QUALITY;
+    } else {
+	type = large_filter ? SRC_SINC_FASTEST : SRC_LINEAR;
+    }
+
+    /* Create converter */
+    resample->state = src_new(type, channel_count, &err);
+    if (resample->state == NULL) {
+	PJ_LOG(4,(THIS_FILE, "Error creating resample: %s", 
+		  src_strerror(err)));
+	return PJMEDIA_ERROR;
+    }
+
+    /* Calculate ratio */
+    resample->ratio = rate_out * 1.0 / rate_in;
+
+    /* Calculate number of samples for input and output */
+    resample->in_samples = samples_per_frame;
+    resample->out_samples = rate_out / (rate_in / samples_per_frame);
+
+    resample->frame_in = (float*) 
+			 pj_pool_calloc(pool, 
+					resample->in_samples + 8, 
+					sizeof(float));
+
+    resample->frame_out = (float*) 
+			  pj_pool_calloc(pool, 
+					 resample->out_samples + 8, 
+					 sizeof(float));
+
+    /* Set the converter ratio */
+    err = src_set_ratio(resample->state, resample->ratio);
+    if (err != 0) {
+	PJ_LOG(4,(THIS_FILE, "Error creating resample: %s", 
+		  src_strerror(err)));
+	return PJMEDIA_ERROR;
+    }
+
+    /* Done */
+
+    PJ_LOG(5,(THIS_FILE, 
+	      "Resample using libsamplerate %s, type=%s (%s), "
+	      "ch=%d, in/out rate=%d/%d", 
+	      src_get_version(),
+	      src_get_name(type), src_get_description(type),
+	      channel_count, rate_in, rate_out));
+
+    *p_resample = resample;
+
+    return PJ_SUCCESS;
+}
+
+
+PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,
+				   const pj_int16_t *input,
+				   pj_int16_t *output )
+{
+    SRC_DATA src_data;
+
+    /* Convert samples to float */
+    src_short_to_float_array(input, resample->frame_in, 
+			     resample->in_samples);
+
+    if (resample->in_extra) {
+	unsigned i;
+
+	for (i=0; i<resample->in_extra; ++i)
+	    resample->frame_in[resample->in_samples+i] =
+		resample->frame_in[resample->in_samples-1];
+    }
+
+    /* Prepare SRC_DATA */
+    pj_bzero(&src_data, sizeof(src_data));
+    src_data.data_in = resample->frame_in;
+    src_data.data_out = resample->frame_out;
+    src_data.input_frames = resample->in_samples + resample->in_extra;
+    src_data.output_frames = resample->out_samples + resample->out_extra;
+    src_data.src_ratio = resample->ratio;
+
+    /* Process! */
+    src_process(resample->state, &src_data);
+
+    /* Convert output back to short */
+    src_float_to_short_array(resample->frame_out, output,
+			     src_data.output_frames_gen);
+
+    /* Replay last sample if conversion couldn't fill up the whole 
+     * frame. This could happen for example with 22050 to 16000 conversion.
+     */
+    if (src_data.output_frames_gen < (int)resample->out_samples) {
+	unsigned i;
+
+	if (resample->in_extra < 4)
+	    resample->in_extra++;
+
+	for (i=src_data.output_frames_gen; 
+	     i<resample->out_samples; ++i)
+	{
+	    output[i] = output[src_data.output_frames_gen-1];
+	}
+    }
+}
+
+
+PJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample)
+{
+    PJ_ASSERT_RETURN(resample != NULL, 0);
+    return resample->in_samples;
+}
+
+
+PJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample)
+{
+    PJ_ASSERT_ON_FAIL(resample, return);
+    if (resample->state) {
+	src_delete(resample->state);
+	resample->state = NULL;
+
+	PJ_LOG(5,(THIS_FILE, "Resample destroyed"));
+    }
+}
+
+#else /* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE */
+
+int pjmedia_libsamplerate_excluded;
+
+#endif	/* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBSAMPLERATE */
+
diff --git a/pjmedia/src/pjmedia/resample_resample.c b/pjmedia/src/pjmedia/resample_resample.c
index e013748..d3b53d9 100644
--- a/pjmedia/src/pjmedia/resample_resample.c
+++ b/pjmedia/src/pjmedia/resample_resample.c
@@ -25,7 +25,7 @@
 #include <pj/pool.h>
 
 
-#if defined(PJMEDIA_HAS_LIBRESAMPLE) && PJMEDIA_HAS_LIBRESAMPLE != 0
+#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBRESAMPLE
 
 #include <third_party/resample/include/resamplesubs.h>
 
@@ -215,16 +215,11 @@
 }
 
 
-#else /* PJMEDIA_HAS_LIBRESAMPLE */
+#elif PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_NONE
 
 /*
  * This is the configuration when sample rate conversion is disabled.
  */
-struct pjmedia_resample
-{
-	unsigned samples_per_frame;
-};
-
 PJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,
 					     pj_bool_t high_quality,
 					     pj_bool_t large_filter,
@@ -234,40 +229,37 @@
 					     unsigned samples_per_frame,
 					     pjmedia_resample **p_resample) 
 {
-	pjmedia_resample *resample;
-	
-	PJ_ASSERT_RETURN(rate_in == rate_out, PJ_EINVALIDOP);
+    PJ_UNUSED_ARG(pool);
+    PJ_UNUSED_ARG(high_quality);
+    PJ_UNUSED_ARG(large_filter);
+    PJ_UNUSED_ARG(channel_count);
+    PJ_UNUSED_ARG(rate_in);
+    PJ_UNUSED_ARG(rate_out);
+    PJ_UNUSED_ARG(samples_per_frame);
+    PJ_UNUSED_ARG(p_resample);
 
-	PJ_UNUSED_ARG(high_quality);
-	PJ_UNUSED_ARG(large_filter);
-	PJ_UNUSED_ARG(channel_count);
-	PJ_UNUSED_ARG(rate_in);
-	PJ_UNUSED_ARG(rate_out);
-		
-	resample = PJ_POOL_ZALLOC_T(pool, pjmedia_resample);
-	resample->samples_per_frame = samples_per_frame;
-	
-	*p_resample = resample;
-	
-	return PJ_SUCCESS;
+    return PJ_EINVALIDOP;
 }
 
 PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,
 				   const pj_int16_t *input,
 				   pj_int16_t *output ) 
 {
-	pjmedia_copy_samples(output, input, resample->samples_per_frame);
+    PJ_UNUSED_ARG(resample);
+    PJ_UNUSED_ARG(input);
+    PJ_UNUSED_ARG(output);
 }
 
 PJ_DEF(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample) 
 {
-	return resample->samples_per_frame;
+    PJ_UNUSED_ARG(resample);
+    return 0;
 }
 
 PJ_DEF(void) pjmedia_resample_destroy(pjmedia_resample *resample) 
 {
-	PJ_UNUSED_ARG(resample);
+    PJ_UNUSED_ARG(resample);
 }
 
-#endif	/* PJMEDIA_HAS_LIBRESAMPLE */
+#endif	/* PJMEDIA_RESAMPLE_IMP */
 
diff --git a/pjmedia/src/pjmedia/resample_speex.c b/pjmedia/src/pjmedia/resample_speex.c
index fcc4211..fc73b78 100644
--- a/pjmedia/src/pjmedia/resample_speex.c
+++ b/pjmedia/src/pjmedia/resample_speex.c
@@ -22,7 +22,7 @@
 #include <pj/log.h>
 #include <pj/pool.h>
 
-#if defined(PJMEDIA_HAS_SPEEX_RESAMPLE) && PJMEDIA_HAS_SPEEX_RESAMPLE != 0
+#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX
 
 #include <speex/speex_resampler.h>
 
@@ -118,9 +118,9 @@
     }
 }
 
-#else /* PJMEDIA_HAS_SPEEX_RESAMPLE */
+#else /* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX */
 
 int pjmedia_resample_speex_excluded;
 
-#endif	/* PJMEDIA_HAS_SPEEX_RESAMPLE */
+#endif	/* PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_SPEEX */
 
diff --git a/third_party/build/samplerate/README.txt b/third_party/build/samplerate/README.txt
new file mode 100644
index 0000000..4883259
--- /dev/null
+++ b/third_party/build/samplerate/README.txt
@@ -0,0 +1,74 @@
+
+                      HOW TO ACTIVATE LIBSAMPLERATE 
+                      (a.k.a SRC/Secret Rabbit Code)
+                AS PJMEDIA'S SAMPLE RATE CONVERSION BACKEND
+
+                                   by
+                              Benny Prijono
+                                  PJSIP
+
+Background
+----------
+   Secret Rabbit Code (aka libsamplerate) is a sample rate conversion
+   library, available from http://www.mega-nerd.com/SRC/index.html.
+   It is licensed under dual license, GPL and proprietary.
+
+   
+Supported Platforms
+-------------------
+   libsamplerate is available for Win32 with Visual Studio and the
+   Makefile based targets (such as Linux, MacOS X, *nix, etc.).
+
+   It's not supported for WinCE/Windows Mobile and Symbian since it is
+   a floating point based implementation.
+
+   
+Installation
+------------
+   - Download libsamplerate from http://www.mega-nerd.com/SRC/index.html
+
+   - Untar libsamplerate-0.1.2.tar.gz into third_party directory
+       cd third_party
+       tar xzf libsamplerate-0.1.2.tar.gz
+
+   - Rename libsamplerate-0.1.2 directory name to libsamplerate
+       On Windows:
+          ren libsamplerate-0.1.2 libsamplerate
+
+       On Linux/Unix/MacOS X:
+          mv libsamplerate-0.1.2 libsamplerate
+
+
+Visual Studio Build
+-------------------
+   For Visual Studio projects, only static linkage is supported 
+   by PJMEDIA build system. If dynamic linking is desired, edit
+   pjmedia/src/pjmedia/resample_libresample.c to prevent it from
+   linking with the static library, and configure your project
+   to link with libsamplerate DLL library.
+ 
+   To build libresample static library with Visual Studio:
+
+      - Open third_party/build/samplerate/libsamplerate_static.dsp
+      - Build the project for both Debug and Release build
+
+
+   libresample dynamic library can be produced by following the
+   instructions in libresample source directory.
+   
+
+Makefile build
+--------------
+   libsamplerate build is integrated with PJSIP's build system.
+
+   TBD.
+
+
+Enabling libsamplerate for PJMEDIA's resample
+---------------------------------------------
+    Add this in config_site.h:
+
+      #define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBSAMPLERATE
+
+
+
diff --git a/third_party/build/samplerate/Static.msvc b/third_party/build/samplerate/Static.msvc
new file mode 100644
index 0000000..0f04c8f
--- /dev/null
+++ b/third_party/build/samplerate/Static.msvc
@@ -0,0 +1,138 @@
+

+!IF "$(OS)" == "Windows_NT"

+NULL=

+!ELSE 

+NULL=nul

+!ENDIF 

+

+CPP=cl.exe

+RSC=rc.exe

+F90=df.exe

+BSC32=bscmake.exe

+BSC32_SBRS= \

+	

+LIB32=link.exe -lib

+

+OUTDIR_REL=.\output\libsamplerate-i386-win32-vc-release

+INTDIR_REL=.\output\libsamplerate-i386-win32-vc-release

+OUTDIR_DEB=.\output\libsamplerate-i386-win32-vc-debug

+INTDIR_DEB=.\output\libsamplerate-i386-win32-vc-debug

+

+LIB_REL=..\..\lib\libsamplerate-i386-win32-vc-release.lib

+LIB_DEB=..\..\lib\libsamplerate-i386-win32-vc-debug.lib

+

+ALL : $(LIB_REL) $(LIB_DEB)

+

+CLEAN :

+	-@erase "$(INTDIR_REL)\*.obj"

+	-@erase "$(INTDIR_REL)\*.pch"

+	-@erase "$(INTDIR_REL)\*.pdb"

+	-@erase "$(INTDIR_REL)\*.idb"

+	@rmdir $(INTDIR_REL)

+	-@erase "$(INTDIR_DEB)\*.obj"

+	-@erase "$(INTDIR_DEB)\*.pch"

+	-@erase "$(INTDIR_DEB)\*.pdb"

+	-@erase "$(INTDIR_DEB)\*.idb"

+	@rmdir $(INTDIR_DEB)

+	-@erase $(LIB_REL)

+	-@erase $(LIB_DEB)

+

+"$(OUTDIR_REL)" :

+    if not exist "$(OUTDIR_REL)/$(NULL)" mkdir "$(OUTDIR_REL)"

+

+CPP_PROJ_REL=/nologo /MD /W3 /GX /O2 /I "../win32" /I "../../libsamplerate/src" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR_REL)\libsamplerate_static.pch" /YX /Fo"$(INTDIR_REL)\\" /Fd"$(INTDIR_REL)\\" /FD /c 

+	

+LIB32_FLAGS_REL=/nologo /out:$(LIB_REL)

+LIB32_OBJS_REL= \

+	"$(INTDIR_REL)\samplerate.obj" \

+	"$(INTDIR_REL)\src_linear.obj" \

+	"$(INTDIR_REL)\src_sinc.obj" \

+	"$(INTDIR_REL)\src_zoh.obj"

+

+$(LIB_REL) : "$(OUTDIR_REL)" $(DEF_FILE) $(LIB32_OBJS_REL)

+    $(LIB32) @<<

+  $(LIB32_FLAGS_REL) $(DEF_FLAGS) $(LIB32_OBJS_REL)

+<<

+

+"$(OUTDIR_DEB)" :

+    if not exist "$(OUTDIR_DEB)/$(NULL)" mkdir "$(OUTDIR_DEB)"

+

+CPP_PROJ_DEB=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "../win32" /I "../../libsamplerate/src" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR_DEB)\libsamplerate_static.pch" /YX /Fo"$(INTDIR_DEB)\\" /Fd"$(INTDIR_DEB)\\" /FD /GZ /c 

+LIB32_FLAGS_DEB=/nologo /out:$(LIB_DEB)

+LIB32_OBJS_DEB= \

+	"$(INTDIR_DEB)\samplerate.obj" \

+	"$(INTDIR_DEB)\src_linear.obj" \

+	"$(INTDIR_DEB)\src_sinc.obj" \

+	"$(INTDIR_DEB)\src_zoh.obj"

+

+$(LIB_DEB) : "$(OUTDIR_DEB)" $(DEF_FILE) $(LIB32_OBJS_DEB)

+    $(LIB32) @<<

+  $(LIB32_FLAGS_DEB) $(DEF_FLAGS) $(LIB32_OBJS_DEB)

+<<

+

+

+..\..\libsamplerate\src\samplerate.c : \

+	"..\..\libsamplerate\src\common.h"\

+	"..\..\libsamplerate\src\config.h"\

+	"..\..\libsamplerate\src\float_cast.h"\

+	"..\..\libsamplerate\src\samplerate.h"\

+	

+

+..\..\libsamplerate\src\src_linear.c : \

+	"..\..\libsamplerate\src\common.h"\

+	"..\..\libsamplerate\src\config.h"\

+	"..\..\libsamplerate\src\float_cast.h"\

+	"..\..\libsamplerate\src\samplerate.h"\

+	

+

+..\..\libsamplerate\src\src_sinc.c : \

+	"..\..\libsamplerate\src\common.h"\

+	"..\..\libsamplerate\src\config.h"\

+	"..\..\libsamplerate\src\fastest_coeffs.h"\

+	"..\..\libsamplerate\src\float_cast.h"\

+	"..\..\libsamplerate\src\high_qual_coeffs.h"\

+	"..\..\libsamplerate\src\mid_qual_coeffs.h"\

+	"..\..\libsamplerate\src\samplerate.h"\

+	

+

+..\..\libsamplerate\src\src_zoh.c : \

+	"..\..\libsamplerate\src\common.h"\

+	"..\..\libsamplerate\src\config.h"\

+	"..\..\libsamplerate\src\float_cast.h"\

+	"..\..\libsamplerate\src\samplerate.h"\

+	

+

+

+SOURCE=..\..\libsamplerate\src\samplerate.c

+

+"$(INTDIR_DEB)\samplerate.obj" : $(SOURCE) "$(INTDIR_DEB)"

+	$(CPP) $(CPP_PROJ_DEB) $(SOURCE)

+"$(INTDIR_REL)\samplerate.obj" : $(SOURCE) "$(INTDIR_REL)"

+	$(CPP) $(CPP_PROJ_REL) $(SOURCE)

+

+

+SOURCE=..\..\libsamplerate\src\src_linear.c

+

+"$(INTDIR_DEB)\src_linear.obj" : $(SOURCE) "$(INTDIR_DEB)"

+	$(CPP) $(CPP_PROJ_DEB) $(SOURCE)

+"$(INTDIR_REL)\src_linear.obj" : $(SOURCE) "$(INTDIR_REL)"

+	$(CPP) $(CPP_PROJ_REL) $(SOURCE)

+

+

+SOURCE=..\..\libsamplerate\src\src_sinc.c

+

+"$(INTDIR_DEB)\src_sinc.obj" : $(SOURCE) "$(INTDIR_DEB)"

+	$(CPP) $(CPP_PROJ_DEB) $(SOURCE)

+"$(INTDIR_REL)\src_sinc.obj" : $(SOURCE) "$(INTDIR_REL)"

+	$(CPP) $(CPP_PROJ_REL) $(SOURCE)

+

+

+SOURCE=..\..\libsamplerate\src\src_zoh.c

+

+"$(INTDIR_DEB)\src_zoh.obj" : $(SOURCE) "$(INTDIR_DEB)"

+	$(CPP) $(CPP_PROJ_DEB) $(SOURCE)

+"$(INTDIR_REL)\src_zoh.obj" : $(SOURCE) "$(INTDIR_REL)"

+	$(CPP) $(CPP_PROJ_REL) $(SOURCE)

+

+

+

diff --git a/third_party/build/samplerate/libsamplerate_static.dsp b/third_party/build/samplerate/libsamplerate_static.dsp
new file mode 100644
index 0000000..54ac8e3
--- /dev/null
+++ b/third_party/build/samplerate/libsamplerate_static.dsp
@@ -0,0 +1,114 @@
+# Microsoft Developer Studio Project File - Name="libsamplerate_static" - Package Owner=<4>

+# Microsoft Developer Studio Generated Build File, Format Version 6.00

+# ** DO NOT EDIT **

+

+# TARGTYPE "Win32 (x86) Static Library" 0x0104

+

+CFG=libsamplerate_static - Win32 Debug

+!MESSAGE This is not a valid makefile. To build this project using NMAKE,

+!MESSAGE use the Export Makefile command and run

+!MESSAGE 

+!MESSAGE NMAKE /f "libsamplerate_static.mak".

+!MESSAGE 

+!MESSAGE You can specify a configuration when running NMAKE

+!MESSAGE by defining the macro CFG on the command line. For example:

+!MESSAGE 

+!MESSAGE NMAKE /f "libsamplerate_static.mak" CFG="libsamplerate_static - Win32 Debug"

+!MESSAGE 

+!MESSAGE Possible choices for configuration are:

+!MESSAGE 

+!MESSAGE "libsamplerate_static - Win32 Release" (based on "Win32 (x86) Static Library")

+!MESSAGE "libsamplerate_static - Win32 Debug" (based on "Win32 (x86) Static Library")

+!MESSAGE 

+

+# Begin Project

+# PROP AllowPerConfigDependencies 0

+# PROP Scc_ProjName ""

+# PROP Scc_LocalPath ""

+CPP=cl.exe

+RSC=rc.exe

+

+!IF  "$(CFG)" == "libsamplerate_static - Win32 Release"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 0

+# PROP BASE Output_Dir "output/libsamplerate-i386-win32-vc-release"

+# PROP BASE Intermediate_Dir "output/libsamplerate-i386-win32-vc-release"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 0

+# PROP Output_Dir "output/libsamplerate-i386-win32-vc-release"

+# PROP Intermediate_Dir "output/libsamplerate-i386-win32-vc-release"

+# PROP Target_Dir ""

+F90=df.exe

+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c

+# ADD CPP /nologo /MD /W3 /GX /O2 /I "./win32" /I "../../libsamplerate/src" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c

+# ADD BASE RSC /l 0x409 /d "NDEBUG"

+# ADD RSC /l 0x409 /d "NDEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LIB32=link.exe -lib

+# ADD BASE LIB32 /nologo

+# ADD LIB32 /nologo /out:"..\..\lib\libsamplerate-i386-win32-vc-release.lib"

+

+!ELSEIF  "$(CFG)" == "libsamplerate_static - Win32 Debug"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 1

+# PROP BASE Output_Dir "output/libsamplerate-i386-win32-vc-debug"

+# PROP BASE Intermediate_Dir "output/libsamplerate-i386-win32-vc-debug"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 1

+# PROP Output_Dir "output/libsamplerate-i386-win32-vc-debug"

+# PROP Intermediate_Dir "output/libsamplerate-i386-win32-vc-debug"

+# PROP Target_Dir ""

+F90=df.exe

+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c

+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "./win32" /I "../../libsamplerate/src" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c

+# ADD BASE RSC /l 0x409 /d "_DEBUG"

+# ADD RSC /l 0x409 /d "_DEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LIB32=link.exe -lib

+# ADD BASE LIB32 /nologo

+# ADD LIB32 /nologo /out:"..\..\lib\libsamplerate-i386-win32-vc-debug.lib"

+

+!ENDIF 

+

+# Begin Target

+

+# Name "libsamplerate_static - Win32 Release"

+# Name "libsamplerate_static - Win32 Debug"

+# Begin Group "Source Files"

+

+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+# Begin Source File

+

+SOURCE=..\..\libsamplerate\src\samplerate.c

+# End Source File

+# Begin Source File

+

+SOURCE=..\..\libsamplerate\src\src_linear.c

+# End Source File

+# Begin Source File

+

+SOURCE=..\..\libsamplerate\src\src_sinc.c

+# End Source File

+# Begin Source File

+

+SOURCE=..\..\libsamplerate\src\src_zoh.c

+# End Source File

+# End Group

+# Begin Group "Header Files"

+

+# PROP Default_Filter "h;hpp;hxx;hm;inl"

+# Begin Source File

+

+SOURCE=..\..\libsamplerate\src\samplerate.h

+# End Source File

+# End Group

+# End Target

+# End Project