Unified · Split
| @@ -159,6 +159,7 @@ if (NOT HAVE_SYS_SOUNDCARD_H) · 158 unmodified lines | |||
| 159 | endif (NOT HAVE_SYS_SOUNDCARD_H) | 159 | endif (NOT HAVE_SYS_SOUNDCARD_H) |
| 160 | optional(HAVE_WAVEAUDIO mmsystem.h winmm waveInGetDevCapsA waveaudio) | 160 | optional(HAVE_WAVEAUDIO mmsystem.h winmm waveInGetDevCapsA waveaudio) |
| 161 | optional4(HAVE_OGG_VORBIS vorbis/codec.h ogg ogg_stream_flush vorbis vorbis_analysis_headerout vorbisfile ov_clear vorbisenc vorbis_encode_init_vbr vorbis) | 161 | optional4(HAVE_OGG_VORBIS vorbis/codec.h ogg ogg_stream_flush vorbis vorbis_analysis_headerout vorbisfile ov_clear vorbisenc vorbis_encode_init_vbr vorbis) |
| 162 | optional3(HAVE_OPUS opusfile.h ogg ogg_stream_flush opus opus_encoder_create opusfile op_open_callbacks opus) | ||
| 162 | optional(HAVE_WAVPACK wavpack/wavpack.h wavpack WavpackGetSampleRate wavpack) | 163 | optional(HAVE_WAVPACK wavpack/wavpack.h wavpack WavpackGetSampleRate wavpack) |
| 163 | 164 | ||
| 164 | if (HAVE_LAME_LAME_H OR HAVE_MAD_H) | 165 | if (HAVE_LAME_LAME_H OR HAVE_MAD_H) |
| @@ -427,6 +427,11 @@ AC_OPTIONAL_FORMAT(oggvorbis, OGG_VORBIS, [AC_CHECK_HEADER(vorbis/codec.h, · 426 unmodified lines | |||
| 427 | AC_CHECK_LIB(vorbisenc, vorbis_encode_init_vbr, OGG_VORBIS_LIBS="-lvorbisenc $OGG_VORBIS_LIBS", using_oggvorbis=no, $OGG_VORBIS_LIBS)], | 427 | AC_CHECK_LIB(vorbisenc, vorbis_encode_init_vbr, OGG_VORBIS_LIBS="-lvorbisenc $OGG_VORBIS_LIBS", using_oggvorbis=no, $OGG_VORBIS_LIBS)], |
| 428 | using_oggvorbis=no)]) | 428 | using_oggvorbis=no)]) |
| 429 | 429 | ||
| 430 | # Check for Opus | ||
| 431 | AC_OPTIONAL_FORMAT(opus, OPUS, | ||
| 432 | [PKG_CHECK_MODULES(OPUS, [opusfile], [], using_opus=no)], | ||
| 433 | using_opus=no) | ||
| 434 | |||
| 430 | 435 | ||
| 431 | 436 | ||
| 432 | # Check for FLAC libraries | 437 | # Check for FLAC libraries |
| @@ -673,6 +678,7 @@ if test "x$using_twolame" = "xyes"; then · 240 unmodified lines | |||
| 673 | echo " dlopen twolame............$enable_dl_twolame" | 678 | echo " dlopen twolame............$enable_dl_twolame" |
| 674 | fi | 679 | fi |
| 675 | echo "oggvorbis..................$using_oggvorbis" | 680 | echo "oggvorbis..................$using_oggvorbis" |
| 681 | echo "opus.......................$using_opus" | ||
| 676 | echo "sndfile....................$using_sndfile" | 682 | echo "sndfile....................$using_sndfile" |
| 677 | if test "x$using_sndfile" = "xyes"; then | 683 | if test "x$using_sndfile" = "xyes"; then |
| 678 | echo " dlopen sndfile............$enable_dl_sndfile" | 684 | echo " dlopen sndfile............$enable_dl_sndfile" |
| @@ -57,6 +57,7 @@ static char const * auto_detect_format(sox_format_t * ft, char const * ext) · 56 unmodified lines | |||
| 57 | CHECK(txw , 0, 0, "" , 0, 6, "LM8953") | 57 | CHECK(txw , 0, 0, "" , 0, 6, "LM8953") |
| 58 | CHECK(sndt , 0, 0, "" , 0, 6, "SOUND\x1a") | 58 | CHECK(sndt , 0, 0, "" , 0, 6, "SOUND\x1a") |
| 59 | CHECK(vorbis, 0, 4, "OggS" , 29, 6, "vorbis") | 59 | CHECK(vorbis, 0, 4, "OggS" , 29, 6, "vorbis") |
| 60 | CHECK(opus , 0, 4, "OggS" , 28, 8, "OpusHead") | ||
| 60 | CHECK(speex , 0, 4, "OggS" , 28, 6, "Speex") | 61 | CHECK(speex , 0, 4, "OggS" , 28, 6, "Speex") |
| 61 | CHECK(hcom ,65, 4, "FSSD" , 128,4, "HCOM") | 62 | CHECK(hcom ,65, 4, "FSSD" , 128,4, "HCOM") |
| 62 | CHECK(wav , 0, 4, "RIFF" , 8, 4, "WAVE") | 63 | CHECK(wav , 0, 4, "RIFF" , 8, 4, "WAVE") |
| @@ -142,6 +143,7 @@ static sox_encodings_info_t const s_sox_encodings_info[] = { · 79 unmodified lines | |||
| 142 | {sox_encodings_lossy2, "AMR-NB" , "AMR-NB"}, | 143 | {sox_encodings_lossy2, "AMR-NB" , "AMR-NB"}, |
| 143 | {sox_encodings_lossy2, "CVSD" , "CVSD"}, | 144 | {sox_encodings_lossy2, "CVSD" , "CVSD"}, |
| 144 | {sox_encodings_lossy2, "LPC10" , "LPC10"}, | 145 | {sox_encodings_lossy2, "LPC10" , "LPC10"}, |
| 146 | {sox_encodings_lossy2, "Opus" , "Opus"}, | ||
| 145 | }; | 147 | }; |
| 146 | 148 | ||
| 147 | assert_static(array_length(s_sox_encodings_info) == SOX_ENCODINGS, | 149 | assert_static(array_length(s_sox_encodings_info) == SOX_ENCODINGS, |
| @@ -182,6 +184,7 @@ unsigned sox_precision(sox_encoding_t encoding, unsigned bits_per_sample) · 34 unmodified lines | |||
| 182 | 184 | ||
| 183 | case SOX_ENCODING_GSM: | 185 | case SOX_ENCODING_GSM: |
| 184 | case SOX_ENCODING_VORBIS: | 186 | case SOX_ENCODING_VORBIS: |
| 187 | case SOX_ENCODING_OPUS: | ||
| 185 | case SOX_ENCODING_AMR_WB: | 188 | case SOX_ENCODING_AMR_WB: |
| 186 | case SOX_ENCODING_AMR_NB: | 189 | case SOX_ENCODING_AMR_NB: |
| 187 | case SOX_ENCODING_LPC10: return !bits_per_sample? 16: 0; | 190 | case SOX_ENCODING_LPC10: return !bits_per_sample? 16: 0; |
| @@ -92,6 +92,9 @@ · 91 unmodified lines | |||
| 92 | #if defined HAVE_MP3 && (defined STATIC_MP3 || !defined HAVE_LIBLTDL) | 92 | #if defined HAVE_MP3 && (defined STATIC_MP3 || !defined HAVE_LIBLTDL) |
| 93 | FORMAT(mp3) | 93 | FORMAT(mp3) |
| 94 | #endif | 94 | #endif |
| 95 | #if defined HAVE_OPUS && (defined STATIC_OPUS || !defined HAVE_LIBLTDL) | ||
| 96 | FORMAT(opus) | ||
| 97 | #endif | ||
| 95 | #if defined HAVE_OSS && (defined STATIC_OSS || !defined HAVE_LIBLTDL) | 98 | #if defined HAVE_OSS && (defined STATIC_OSS || !defined HAVE_LIBLTDL) |
| 96 | FORMAT(oss) | 99 | FORMAT(oss) |
| 97 | #endif | 100 | #endif |
| @@ -135,6 +135,23 @@ else · 134 unmodified lines | |||
| 135 | endif | 135 | endif |
| 136 | endif | 136 | endif |
| 137 | 137 | ||
| 138 | if HAVE_OPUS | ||
| 139 | if STATIC_OPUS | ||
| 140 | libsox_la_SOURCES += opus.c | ||
| 141 | libsox_la_CFLAGS += @OPUS_CFLAGS@ -Wno-long-long | ||
| 142 | if STATIC_LIBSOX_ONLY | ||
| 143 | sox_LDADD += @OPUS_LIBS@ | ||
| 144 | else | ||
| 145 | libsox_la_LIBADD += @OPUS_LIBS@ | ||
| 146 | endif | ||
| 147 | else | ||
| 148 | libsox_fmt_opus_la_SOURCES = opus.c | ||
| 149 | libsox_fmt_opus_la_CFLAGS = @OPUS_CFLAGS@ -Wno-long-long | ||
| 150 | libsox_fmt_opus_la_LIBADD = libsox.la @OPUS_LIBS@ | ||
| 151 | pkglib_LTLIBRARIES += libsox_fmt_opus.la | ||
| 152 | endif | ||
| 153 | endif | ||
| 154 | |||
| 138 | if HAVE_OSS | 155 | if HAVE_OSS |
| 139 | if STATIC_OSS | 156 | if STATIC_OSS |
| 140 | libsox_la_SOURCES += oss.c | 157 | libsox_la_SOURCES += oss.c |
| @@ -0,0 +1,235 @@ | |||
| 1 | /* libSoX Opus-in-Ogg sound format handler | ||
| 2 | * Copyright (C) 2013 John Stumpo <stump@jstump.com> | ||
| 3 | * | ||
| 4 | * Largely based on vorbis.c: | ||
| 5 | * libSoX Ogg Vorbis sound format handler | ||
| 6 | * Copyright 2001, Stan Seibert <indigo@aztec.asu.edu> | ||
| 7 | * | ||
| 8 | * Portions from oggenc, (c) Michael Smith <msmith@labyrinth.net.au>, | ||
| 9 | * ogg123, (c) Kenneth Arnold <kcarnold@yahoo.com>, and | ||
| 10 | * libvorbisfile (c) Xiphophorus Company | ||
| 11 | * | ||
| 12 | * May 9, 2001 - Stan Seibert (indigo@aztec.asu.edu) | ||
| 13 | * Ogg Vorbis handler initially written. | ||
| 14 | * | ||
| 15 | * July 5, 1991 - Skeleton file | ||
| 16 | * Copyright 1991 Lance Norskog And Sundry Contributors | ||
| 17 | * This source code is freely redistributable and may be used for | ||
| 18 | * any purpose. This copyright notice must be maintained. | ||
| 19 | * Lance Norskog And Sundry Contributors are not responsible for | ||
| 20 | * the consequences of using this software. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include "sox_i.h" | ||
| 24 | |||
| 25 | #include <stdio.h> | ||
| 26 | #include <string.h> | ||
| 27 | #include <errno.h> | ||
| 28 | |||
| 29 | #include <opusfile.h> | ||
| 30 | |||
| 31 | #define DEF_BUF_LEN 4096 | ||
| 32 | |||
| 33 | #define BUF_ERROR -1 | ||
| 34 | #define BUF_EOF 0 | ||
| 35 | #define BUF_DATA 1 | ||
| 36 | |||
| 37 | typedef struct { | ||
| 38 | /* Decoding data */ | ||
| 39 | OggOpusFile *of; | ||
| 40 | char *buf; | ||
| 41 | size_t buf_len; | ||
| 42 | size_t start; | ||
| 43 | size_t end; /* Unsent data samples in buf[start] through buf[end-1] */ | ||
| 44 | int current_section; | ||
| 45 | int eof; | ||
| 46 | } priv_t; | ||
| 47 | |||
| 48 | /******** Callback functions used in op_open_callbacks ************/ | ||
| 49 | |||
| 50 | static int callback_read(void* ft_data, unsigned char* ptr, int nbytes) | ||
| 51 | { | ||
| 52 | sox_format_t* ft = (sox_format_t*)ft_data; | ||
| 53 | return lsx_readbuf(ft, ptr, (size_t)nbytes); | ||
| 54 | } | ||
| 55 | |||
| 56 | static int callback_seek(void* ft_data, opus_int64 off, int whence) | ||
| 57 | { | ||
| 58 | sox_format_t* ft = (sox_format_t*)ft_data; | ||
| 59 | int ret = ft->seekable ? lsx_seeki(ft, (off_t)off, whence) : -1; | ||
| 60 | |||
| 61 | if (ret == EBADF) | ||
| 62 | ret = -1; | ||
| 63 | return ret; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int callback_close(void* ft_data UNUSED) | ||
| 67 | { | ||
| 68 | /* Do nothing so sox can close the file for us */ | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static opus_int64 callback_tell(void* ft_data) | ||
| 73 | { | ||
| 74 | sox_format_t* ft = (sox_format_t*)ft_data; | ||
| 75 | return lsx_tell(ft); | ||
| 76 | } | ||
| 77 | |||
| 78 | /********************* End callbacks *****************************/ | ||
| 79 | |||
| 80 | |||
| 81 | /* | ||
| 82 | * Do anything required before you start reading samples. | ||
| 83 | * Read file header. | ||
| 84 | * Find out sampling rate, | ||
| 85 | * size and encoding of samples, | ||
| 86 | * mono/stereo/quad. | ||
| 87 | */ | ||
| 88 | static int startread(sox_format_t * ft) | ||
| 89 | { | ||
| 90 | priv_t * vb = (priv_t *) ft->priv; | ||
| 91 | const OpusTags *ot; | ||
| 92 | int i; | ||
| 93 | |||
| 94 | OpusFileCallbacks callbacks = { | ||
| 95 | callback_read, | ||
| 96 | callback_seek, | ||
| 97 | callback_tell, | ||
| 98 | callback_close | ||
| 99 | }; | ||
| 100 | |||
| 101 | /* Init the decoder */ | ||
| 102 | vb->of = op_open_callbacks(ft, &callbacks, NULL, (size_t) 0, NULL); | ||
| 103 | if (vb->of == NULL) { | ||
| 104 | lsx_fail_errno(ft, SOX_EHDR, "Input not an Ogg Opus audio stream"); | ||
| 105 | return (SOX_EOF); | ||
| 106 | } | ||
| 107 | |||
| 108 | /* Get info about the Opus stream */ | ||
| 109 | ot = op_tags(vb->of, -1); | ||
| 110 | |||
| 111 | /* Record audio info */ | ||
| 112 | ft->signal.rate = 48000; /* libopusfile always uses 48 kHz */ | ||
| 113 | ft->encoding.encoding = SOX_ENCODING_OPUS; | ||
| 114 | ft->signal.channels = op_channel_count(vb->of, -1); | ||
| 115 | |||
| 116 | /* op_pcm_total doesn't work on non-seekable files so | ||
| 117 | * skip that step in that case. Also, it reports | ||
| 118 | * "frame"-ish results so we must * channels. | ||
| 119 | */ | ||
| 120 | if (ft->seekable) | ||
| 121 | ft->signal.length = op_pcm_total(vb->of, -1) * ft->signal.channels; | ||
| 122 | |||
| 123 | /* Record comments */ | ||
| 124 | for (i = 0; i < ot->comments; i++) | ||
| 125 | sox_append_comment(&ft->oob.comments, ot->user_comments[i]); | ||
| 126 | |||
| 127 | /* Setup buffer */ | ||
| 128 | vb->buf_len = DEF_BUF_LEN; | ||
| 129 | vb->buf_len -= vb->buf_len % (ft->signal.channels*2); /* 2 bytes per sample */ | ||
| 130 | vb->buf = lsx_calloc(vb->buf_len, sizeof(char)); | ||
| 131 | vb->start = vb->end = 0; | ||
| 132 | |||
| 133 | /* Fill in other info */ | ||
| 134 | vb->eof = 0; | ||
| 135 | vb->current_section = -1; | ||
| 136 | |||
| 137 | return (SOX_SUCCESS); | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | /* Refill the buffer with samples. Returns BUF_EOF if the end of the | ||
| 142 | * Opus data was reached while the buffer was being filled, | ||
| 143 | * BUF_ERROR is something bad happens, and BUF_DATA otherwise */ | ||
| 144 | static int refill_buffer(sox_format_t * ft) | ||
| 145 | { | ||
| 146 | priv_t * vb = (priv_t *) ft->priv; | ||
| 147 | int num_read; | ||
| 148 | |||
| 149 | if (vb->start == vb->end) /* Samples all played */ | ||
| 150 | vb->start = vb->end = 0; | ||
| 151 | |||
| 152 | while (vb->end < vb->buf_len) { | ||
| 153 | num_read = op_read(vb->of, (opus_int16*) (vb->buf + vb->end), | ||
| 154 | (int) ((vb->buf_len - vb->end) / sizeof(opus_int16)), | ||
| 155 | &vb->current_section); | ||
| 156 | if (num_read == 0) | ||
| 157 | return (BUF_EOF); | ||
| 158 | else if (num_read == OP_HOLE) | ||
| 159 | lsx_warn("Warning: hole in stream; probably harmless"); | ||
| 160 | else if (num_read < 0) | ||
| 161 | return (BUF_ERROR); | ||
| 162 | else | ||
| 163 | vb->end += num_read * sizeof(opus_int16) * ft->signal.channels; | ||
| 164 | } | ||
| 165 | return (BUF_DATA); | ||
| 166 | } | ||
| 167 | |||
| 168 | |||
| 169 | /* | ||
| 170 | * Read up to len samples from file. | ||
| 171 | * Convert to signed longs. | ||
| 172 | * Place in buf[]. | ||
| 173 | * Return number of samples read. | ||
| 174 | */ | ||
| 175 | |||
| 176 | static size_t read_samples(sox_format_t * ft, sox_sample_t * buf, size_t len) | ||
| 177 | { | ||
| 178 | priv_t * vb = (priv_t *) ft->priv; | ||
| 179 | size_t i; | ||
| 180 | int ret; | ||
| 181 | sox_sample_t l; | ||
| 182 | |||
| 183 | |||
| 184 | for (i = 0; i < len; i++) { | ||
| 185 | if (vb->start == vb->end) { | ||
| 186 | if (vb->eof) | ||
| 187 | break; | ||
| 188 | ret = refill_buffer(ft); | ||
| 189 | if (ret == BUF_EOF || ret == BUF_ERROR) { | ||
| 190 | vb->eof = 1; | ||
| 191 | if (vb->end == 0) | ||
| 192 | break; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | l = (vb->buf[vb->start + 1] << 24) | ||
| 197 | | (0xffffff & (vb->buf[vb->start] << 16)); | ||
| 198 | *(buf + i) = l; | ||
| 199 | vb->start += 2; | ||
| 200 | } | ||
| 201 | return i; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* | ||
| 205 | * Do anything required when you stop reading samples. | ||
| 206 | * Don't close input file! | ||
| 207 | */ | ||
| 208 | static int stopread(sox_format_t * ft) | ||
| 209 | { | ||
| 210 | priv_t * vb = (priv_t *) ft->priv; | ||
| 211 | |||
| 212 | free(vb->buf); | ||
| 213 | op_free(vb->of); | ||
| 214 | |||
| 215 | return (SOX_SUCCESS); | ||
| 216 | } | ||
| 217 | |||
| 218 | static int seek(sox_format_t * ft, uint64_t offset) | ||
| 219 | { | ||
| 220 | priv_t * vb = (priv_t *) ft->priv; | ||
| 221 | |||
| 222 | return op_pcm_seek(vb->of, (opus_int64)(offset / ft->signal.channels))? SOX_EOF:SOX_SUCCESS; | ||
| 223 | } | ||
| 224 | |||
| 225 | LSX_FORMAT_HANDLER(opus) | ||
| 226 | { | ||
| 227 | static const char *const names[] = {"opus", NULL}; | ||
| 228 | static sox_format_handler_t handler = {SOX_LIB_VERSION_CODE, | ||
| 229 | "Xiph.org's Opus lossy compression", names, 0, | ||
| 230 | startread, read_samples, stopread, | ||
| 231 | NULL, NULL, NULL, | ||
| 232 | seek, NULL, NULL, sizeof(priv_t) | ||
| 233 | }; | ||
| 234 | return &handler; | ||
| 235 | } | ||
| @@ -593,6 +593,7 @@ typedef enum sox_encoding_t { · 592 unmodified lines | |||
| 593 | SOX_ENCODING_AMR_NB , /**< AMR-NB compression */ | 593 | SOX_ENCODING_AMR_NB , /**< AMR-NB compression */ |
| 594 | SOX_ENCODING_CVSD , /**< Continuously Variable Slope Delta modulation */ | 594 | SOX_ENCODING_CVSD , /**< Continuously Variable Slope Delta modulation */ |
| 595 | SOX_ENCODING_LPC10 , /**< Linear Predictive Coding */ | 595 | SOX_ENCODING_LPC10 , /**< Linear Predictive Coding */ |
| 596 | SOX_ENCODING_OPUS , /**< Opus compression */ | ||
| 596 | 597 | ||
| 597 | SOX_ENCODINGS /**< End of list marker */ | 598 | SOX_ENCODINGS /**< End of list marker */ |
| 598 | } sox_encoding_t; | 599 | } sox_encoding_t; |