Support for Ambisonics.

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
diff --git a/include/opus_defines.h b/include/opus_defines.h
index 33c5acd..fbf5d0e 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -169,6 +169,9 @@
 #define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
 #define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
 
+/** Defines for the presence of extended APIs. */
+#define OPUS_HAVE_OPUS_PROJECTION_H
+
 /* Macros to trigger compilation errors when the wrong types are provided to a CTL */
 #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
 #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
diff --git a/src/opus_projection_decoder.c b/src/opus_projection_decoder.c
index d39cb83..c879ead 100644
--- a/src/opus_projection_decoder.c
+++ b/src/opus_projection_decoder.c
@@ -254,4 +254,105 @@
   opus_free(st);
 }
 
+#else /* ENABLE_EXPERIMENTAL_AMBISONICS */
+
+opus_int32 opus_projection_decoder_get_size(
+    int channels,
+    int streams,
+    int coupled_streams)
+{
+  (void)channels;
+  (void)streams;
+  (void)coupled_streams;
+  return OPUS_UNIMPLEMENTED;
+}
+
+OpusProjectionDecoder *opus_projection_decoder_create(
+    opus_int32 Fs,
+    int channels,
+    int streams,
+    int coupled_streams,
+    unsigned char *demixing_matrix,
+    opus_int32 demixing_matrix_size,
+    int *error)
+{
+  (void)Fs;
+  (void)channels;
+  (void)streams;
+  (void)coupled_streams;
+  (void)demixing_matrix;
+  (void)demixing_matrix_size;
+  if (error) *error = OPUS_UNIMPLEMENTED;
+  return NULL;
+}
+
+int opus_projection_decoder_init(
+    OpusProjectionDecoder *st,
+    opus_int32 Fs,
+    int channels,
+    int streams,
+    int coupled_streams,
+    unsigned char *demixing_matrix,
+    opus_int32 demixing_matrix_size)
+{
+  (void)st;
+  (void)Fs;
+  (void)channels;
+  (void)streams;
+  (void)coupled_streams;
+  (void)demixing_matrix;
+  (void)demixing_matrix_size;
+  return OPUS_UNIMPLEMENTED;
+}
+
+int opus_projection_decode(
+    OpusProjectionDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    opus_int16 *pcm,
+    int frame_size,
+    int decode_fec)
+{
+  (void)st;
+  (void)data;
+  (void)len;
+  (void)pcm;
+  (void)frame_size;
+  (void)decode_fec;
+  return OPUS_UNIMPLEMENTED;
+}
+
+int opus_projection_decode_float(
+    OpusProjectionDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    float *pcm,
+    int frame_size,
+    int decode_fec)
+{
+  (void)st;
+  (void)data;
+  (void)len;
+  (void)pcm;
+  (void)frame_size;
+  (void)decode_fec;
+  return OPUS_UNIMPLEMENTED;
+}
+
+int opus_projection_decoder_ctl(
+    OpusProjectionDecoder *st,
+    int request,
+    ...)
+{
+  (void)st;
+  (void)request;
+  return OPUS_UNIMPLEMENTED;
+}
+
+void opus_projection_decoder_destroy(
+    OpusProjectionDecoder *st)
+{
+  (void)st;
+}
+
 #endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
diff --git a/src/opus_projection_encoder.c b/src/opus_projection_encoder.c
index ea2a26b..1c403c3 100644
--- a/src/opus_projection_encoder.c
+++ b/src/opus_projection_encoder.c
@@ -459,4 +459,93 @@
   return OPUS_BAD_ARG;
 }
 
+#else /* ENABLE_EXPERIMENTAL_AMBISONICS */
+
+opus_int32 opus_projection_ambisonics_encoder_get_size(
+    int channels, int mapping_family)
+{
+  (void)channels;
+  (void)mapping_family;
+  return OPUS_UNIMPLEMENTED;
+}
+
+OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
+    opus_int32 Fs, int channels, int mapping_family, int *streams,
+    int *coupled_streams, int application, int *error)
+{
+  (void)Fs;
+  (void)channels;
+  (void)mapping_family;
+  (void)streams;
+  (void)coupled_streams;
+  (void)application;
+  if (error) *error = OPUS_UNIMPLEMENTED;
+  return NULL;
+}
+
+int opus_projection_ambisonics_encoder_init(
+    OpusProjectionEncoder *st,
+    opus_int32 Fs,
+    int channels,
+    int mapping_family,
+    int *streams,
+    int *coupled_streams,
+    int application)
+{
+  (void)st;
+  (void)Fs;
+  (void)channels;
+  (void)mapping_family;
+  (void)streams;
+  (void)coupled_streams;
+  (void)application;
+  return OPUS_UNIMPLEMENTED;
+}
+
+int opus_projection_encode(
+    OpusProjectionEncoder *st,
+    const opus_int16 *pcm,
+    int frame_size,
+    unsigned char *data,
+    opus_int32 max_data_bytes)
+{
+  (void)st;
+  (void)pcm;
+  (void)frame_size;
+  (void)data;
+  (void)max_data_bytes;
+  return OPUS_UNIMPLEMENTED;
+}
+
+int opus_projection_encode_float(
+    OpusProjectionEncoder *st,
+    const float *pcm,
+    int frame_size,
+    unsigned char *data,
+    opus_int32 max_data_bytes)
+{
+  (void)st;
+  (void)pcm;
+  (void)frame_size;
+  (void)data;
+  (void)max_data_bytes;
+  return OPUS_UNIMPLEMENTED;
+}
+
+void opus_projection_encoder_destroy(
+    OpusProjectionEncoder *st)
+{
+  (void)st;
+}
+
+int opus_projection_encoder_ctl(
+    OpusProjectionEncoder *st,
+    int request,
+    ...)
+{
+  (void)st;
+  (void)request;
+  return OPUS_UNIMPLEMENTED;
+}
+
 #endif /* ENABLE_EXPERIMENTAL_AMBISONICS */