1 /*
2 
3 Boost Software License - Version 1.0 - August 17th, 2003
4 
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 
27 */
28 module derelict.vorbis.codec;
29 
30 private {
31     import core.stdc.config;
32     import derelict.util.loader;
33     import derelict.util.system;
34     import derelict.ogg.ogg;
35 
36     static if(Derelict_OS_Windows)
37         enum libNames = "vorbis.dll, libvorbis-0.dll, libvorbis.dll";
38     else static if(Derelict_OS_Mac)
39         enum libNames = "libvorbis.dylib, libvorbis.0.dylib";
40     else static if(Derelict_OS_Posix)
41         enum libNames = "libvorbis.so, libvorbis.so.0, libvorbis.so.0.3.0";
42     else
43         static assert(0, "Need to implement libvorbis libnames for this operating system.");
44 }
45 
46 enum {
47     OV_FALSE      = -1,
48     OV_EOF        = -2,
49     OV_HOLE       = -3,
50     OV_EREAD      = -128,
51     OV_EFAULT     = -129,
52     OV_EIMPL      = -130,
53     OV_EINVAL     = -131,
54     OV_ENOTVORBIS = -132,
55     OV_EBADHEADER = -133,
56     OV_EVERSION   = -134,
57     OV_ENOTAUDIO  = -135,
58     OV_EBADPACKET = -136,
59     OV_EBADLINK   = -137,
60     OV_ENOSEEK    = -138,
61 }
62 
63 struct vorbis_info {
64     int _version; // Renamed from "version", since that's a keyword in D
65     int channels;
66     int rate;
67     c_long bitrate_upper;
68     c_long bitrate_nominal;
69     c_long bitrate_lower;
70     c_long bitrate_window;
71 
72     void *codec_setup;
73 }
74 
75 struct vorbis_dsp_state {
76     int analysisp;
77     vorbis_info* vi;
78     float** pcm;
79     float** pcmret;
80     int pcm_storage;
81     int pcm_current;
82     int pcm_returned;
83     int preextrapolate;
84     int eofflag;
85     c_long lW;
86     c_long W;
87     c_long nW;
88     c_long centerW;
89     ogg_int64_t granulepos;
90     ogg_int64_t sequence;
91     ogg_int64_t glue_bits;
92     ogg_int64_t time_bits;
93     ogg_int64_t floor_bits;
94     ogg_int64_t res_bits;
95     void* backend_state;
96 }
97 
98 
99 struct vorbis_block {
100     float** pcm;
101     oggpack_buffer opb;
102     c_long lW;
103     c_long W;
104     c_long nW;
105     int pcmend;
106     int mode;
107     int eofflag;
108     ogg_int64_t granulepos;
109     ogg_int64_t sequence;
110     vorbis_dsp_state* vd;
111     void* localstore;
112     c_long localtop;
113     c_long localalloc;
114     c_long totaluse;
115     alloc_chain* reap;
116     c_long glue_bits;
117     c_long time_bits;
118     c_long floor_bits;
119     c_long res_bits;
120     void* internal;
121 }
122 
123 struct alloc_chain {
124     void* ptr;
125     alloc_chain* next;
126 }
127 
128 struct vorbis_comment {
129     char** user_comments;
130     int* comment_lengths;
131     int comments;
132     char* vendor;
133 }
134 
135 extern(C) @nogc nothrow {
136     alias da_vorbis_info_init = void function(vorbis_info*);
137     alias da_vorbis_info_clear = void function(vorbis_info*);
138     alias da_vorbis_info_blocksize = int function(vorbis_info*,int);
139     alias da_vorbis_comment_init = void function(vorbis_comment*);
140     alias da_vorbis_comment_add = void function(vorbis_comment*, byte*t);
141     alias da_vorbis_comment_add_tag = void function(vorbis_comment*, byte*, byte*);
142     alias da_vorbis_comment_query = byte* function(vorbis_comment*, byte*, int);
143     alias da_vorbis_comment_query_count = int function(vorbis_comment*, byte*);
144     alias da_vorbis_comment_clear = void function(vorbis_comment*);
145     alias da_vorbis_block_init = int function(vorbis_dsp_state*, vorbis_block*);
146     alias da_vorbis_block_clear = int function(vorbis_block*);
147     alias da_vorbis_dsp_clear = void function(vorbis_dsp_state*);
148     alias da_vorbis_granule_time = double function(vorbis_dsp_state*, ogg_int64_t);
149     alias da_vorbis_version_string = const(char)* function();
150     alias da_vorbis_analysis_init = int function(vorbis_dsp_state*,vorbis_info*);
151     alias da_vorbis_commentheader_out = int function(vorbis_comment*, ogg_packet*);
152     alias da_vorbis_analysis_headerout = int function(vorbis_dsp_state*, vorbis_comment*, ogg_packet*, ogg_packet*, ogg_packet*);
153     alias da_vorbis_analysis_buffer = float** function(vorbis_dsp_state*, int);
154     alias da_vorbis_analysis_wrote = int function(vorbis_dsp_state*, int);
155     alias da_vorbis_analysis_blockout = int function(vorbis_dsp_state*,vorbis_block*);
156     alias da_vorbis_analysis = int function(vorbis_block*,ogg_packet*);
157     alias da_vorbis_bitrate_addblock = int function(vorbis_block*);
158     alias da_vorbis_bitrate_flushpacket = int function(vorbis_dsp_state*, ogg_packet*);
159     alias da_vorbis_synthesis_idheader = int function(ogg_packet*);
160     alias da_vorbis_synthesis_headerin = int function(vorbis_info*, vorbis_comment*, ogg_packet*);
161     alias da_vorbis_synthesis_init = int function(vorbis_dsp_state*, vorbis_info*);
162     alias da_vorbis_synthesis_restart = int function(vorbis_dsp_state*);
163     alias da_vorbis_synthesis = int function(vorbis_block*, ogg_packet*);
164     alias da_vorbis_synthesis_trackonly = int function(vorbis_block*, ogg_packet*);
165     alias da_vorbis_synthesis_blockin = int function(vorbis_dsp_state*,vorbis_block*);
166     alias da_vorbis_synthesis_pcmout = int function(vorbis_dsp_state*, float***);
167     alias da_vorbis_synthesis_lapout = int function(vorbis_dsp_state*, float***);
168     alias da_vorbis_synthesis_read = int function(vorbis_dsp_state*, int);
169     alias da_vorbis_packet_blocksize = c_long function(vorbis_info*,ogg_packet*);
170     alias da_vorbis_synthesis_halfrate = int function(vorbis_info*, int);
171     alias da_vorbis_synthesis_halfrate_p = int function(vorbis_info*);
172 }
173 
174 __gshared {
175     da_vorbis_info_init vorbis_info_init;
176     da_vorbis_info_clear vorbis_info_clear;
177     da_vorbis_info_blocksize vorbis_info_blocksize;
178     da_vorbis_comment_init vorbis_comment_init;
179     da_vorbis_comment_add vorbis_comment_add;
180     da_vorbis_comment_add_tag vorbis_comment_add_tag;
181     da_vorbis_comment_query vorbis_comment_query;
182     da_vorbis_comment_query_count vorbis_comment_query_count;
183     da_vorbis_comment_clear vorbis_comment_clear;
184     da_vorbis_block_init vorbis_block_init;
185     da_vorbis_block_clear vorbis_block_clear;
186     da_vorbis_dsp_clear vorbis_dsp_clear;
187     da_vorbis_granule_time vorbis_granule_time;
188     da_vorbis_version_string vorbis_version_string;
189     da_vorbis_analysis_init vorbis_analysis_init;
190     da_vorbis_commentheader_out vorbis_commentheader_out;
191     da_vorbis_analysis_headerout vorbis_analysis_headerout;
192     da_vorbis_analysis_buffer vorbis_analysis_buffer;
193     da_vorbis_analysis_wrote vorbis_analysis_wrote;
194     da_vorbis_analysis_blockout vorbis_analysis_blockout;
195     da_vorbis_analysis vorbis_analysis;
196     da_vorbis_bitrate_addblock vorbis_bitrate_addblock;
197     da_vorbis_bitrate_flushpacket vorbis_bitrate_flushpacket;
198     da_vorbis_synthesis_idheader vorbis_synthesis_idheader;
199     da_vorbis_synthesis_headerin vorbis_synthesis_headerin;
200     da_vorbis_synthesis_init vorbis_synthesis_init;
201     da_vorbis_synthesis_restart vorbis_synthesis_restart;
202     da_vorbis_synthesis vorbis_synthesis;
203     da_vorbis_synthesis_trackonly vorbis_synthesis_trackonly;
204     da_vorbis_synthesis_blockin vorbis_synthesis_blockin;
205     da_vorbis_synthesis_pcmout vorbis_synthesis_pcmout;
206     da_vorbis_synthesis_lapout vorbis_synthesis_lapout;
207     da_vorbis_synthesis_read vorbis_synthesis_read;
208     da_vorbis_packet_blocksize vorbis_packet_blocksize;
209     da_vorbis_synthesis_halfrate vorbis_synthesis_halfrate;
210     da_vorbis_synthesis_halfrate_p vorbis_synthesis_halfrate_p;
211 }
212 
213 class DerelictVorbisLoader : SharedLibLoader {
214     public this() {
215         super(libNames);
216     }
217 
218     protected override void loadSymbols() {
219         bindFunc(cast(void**)&vorbis_info_init, "vorbis_info_init");
220         bindFunc(cast(void**)&vorbis_info_clear, "vorbis_info_clear");
221         bindFunc(cast(void**)&vorbis_info_blocksize, "vorbis_info_blocksize");
222         bindFunc(cast(void**)&vorbis_comment_init, "vorbis_comment_init");
223         bindFunc(cast(void**)&vorbis_comment_add, "vorbis_comment_add");
224         bindFunc(cast(void**)&vorbis_comment_add_tag, "vorbis_comment_add_tag");
225         bindFunc(cast(void**)&vorbis_comment_query, "vorbis_comment_query");
226         bindFunc(cast(void**)&vorbis_comment_query_count, "vorbis_comment_query_count");
227         bindFunc(cast(void**)&vorbis_comment_clear, "vorbis_comment_clear");
228         bindFunc(cast(void**)&vorbis_block_init, "vorbis_block_init");
229         bindFunc(cast(void**)&vorbis_block_clear, "vorbis_block_clear");
230         bindFunc(cast(void**)&vorbis_dsp_clear, "vorbis_dsp_clear");
231         bindFunc(cast(void**)&vorbis_granule_time, "vorbis_granule_time");
232         bindFunc(cast(void**)&vorbis_version_string, "vorbis_version_string");
233 
234         bindFunc(cast(void**)&vorbis_analysis_init, "vorbis_analysis_init");
235         bindFunc(cast(void**)&vorbis_commentheader_out, "vorbis_commentheader_out");
236         bindFunc(cast(void**)&vorbis_analysis_headerout, "vorbis_analysis_headerout");
237 
238         bindFunc(cast(void**)&vorbis_analysis_buffer, "vorbis_analysis_buffer");
239         bindFunc(cast(void**)&vorbis_analysis_wrote, "vorbis_analysis_wrote");
240         bindFunc(cast(void**)&vorbis_analysis_blockout, "vorbis_analysis_blockout");
241         bindFunc(cast(void**)&vorbis_analysis, "vorbis_analysis");
242 
243         bindFunc(cast(void**)&vorbis_bitrate_addblock, "vorbis_bitrate_addblock");
244         bindFunc(cast(void**)&vorbis_bitrate_flushpacket, "vorbis_bitrate_flushpacket");
245 
246         bindFunc(cast(void**)&vorbis_synthesis_headerin, "vorbis_synthesis_idheader");
247         bindFunc(cast(void**)&vorbis_synthesis_headerin, "vorbis_synthesis_headerin");
248         bindFunc(cast(void**)&vorbis_synthesis_init, "vorbis_synthesis_init");
249         bindFunc(cast(void**)&vorbis_synthesis_restart, "vorbis_synthesis_restart");
250         bindFunc(cast(void**)&vorbis_synthesis, "vorbis_synthesis");
251         bindFunc(cast(void**)&vorbis_synthesis_trackonly, "vorbis_synthesis_trackonly");
252         bindFunc(cast(void**)&vorbis_synthesis_blockin, "vorbis_synthesis_blockin");
253         bindFunc(cast(void**)&vorbis_synthesis_pcmout, "vorbis_synthesis_pcmout");
254         bindFunc(cast(void**)&vorbis_synthesis_lapout, "vorbis_synthesis_lapout");
255         bindFunc(cast(void**)&vorbis_synthesis_read, "vorbis_synthesis_read");
256         bindFunc(cast(void**)&vorbis_packet_blocksize, "vorbis_packet_blocksize");
257         bindFunc(cast(void**)&vorbis_synthesis_halfrate, "vorbis_synthesis_halfrate");
258         bindFunc(cast(void**)&vorbis_synthesis_halfrate_p, "vorbis_synthesis_halfrate_p");
259     }
260 }
261 
262 __gshared DerelictVorbisLoader DerelictVorbis;
263 
264 shared static this() {
265     DerelictVorbis = new DerelictVorbisLoader();
266 }