]>
Commit | Line | Data |
---|---|---|
1 | #define PERL_NO_GET_CONTEXT | |
2 | #include "EXTERN.h" | |
3 | #include "perl.h" | |
4 | #include "XSUB.h" | |
5 | ||
6 | #include "ppport.h" | |
7 | ||
8 | #include <samplerate.h> | |
9 | /* | |
10 | struct generic_callback_data { | |
11 | SV* cb_data; | |
12 | SV* func; | |
13 | int channels; | |
14 | }; | |
15 | ||
16 | long _generic_callback(void *cb_data, float **data){ | |
17 | struct generic_callback_data gc_data; | |
18 | int nr; | |
19 | ||
20 | gc_data = *(struct generic_callback_data*)cb_data; | |
21 | ||
22 | dSP; | |
23 | PUSHMARK(SP); | |
24 | XPUSHs(gc_data.cb_data); | |
25 | PUTBACK; | |
26 | nr = call_sv(gc_data.func, G_ARRAY); | |
27 | SPAGAIN; | |
28 | while(nr--) | |
29 | return nr / | |
30 | } | |
31 | */ | |
32 | ||
33 | /*SV* | |
34 | callback_new(pkg, func, converter_type = 0, channels = 2, cb_data = &PL_sv_undef) | |
35 | const char *pkg | |
36 | SV* pkg | |
37 | int converter_type | |
38 | int channels | |
39 | SV* cb_data | |
40 | PREINIT: | |
41 | int error; | |
42 | SRC_STATE *state; | |
43 | CODE: | |
44 | state = src_new(converter_type, channels, &error); | |
45 | if(state == NULL) { | |
46 | croak("src_new failed with error %d (%s)\n", error, src_strerror(error)); | |
47 | } | |
48 | RETVAL = sv_setref_iv(newSV(0), pkg, PTR2IV(state)); | |
49 | OUTPUT: | |
50 | RETVAL | |
51 | */ | |
52 | ||
53 | #define cerror(func) croak("%s failed with error %d (%s)\n", func, error, src_strerror(error)) | |
54 | #define SELF INT2PTR(SRC_STATE*, SvIV(SvRV(self))) | |
55 | ||
56 | MODULE = Audio::LibSampleRate PACKAGE = Audio::LibSampleRate | |
57 | PROTOTYPES: ENABLE | |
58 | ||
59 | void | |
60 | src_simple(data_in, src_ratio, converter_type = 0, channels = 2) | |
61 | AV* data_in | |
62 | double src_ratio | |
63 | int converter_type | |
64 | int channels | |
65 | PREINIT: | |
66 | SRC_DATA data; | |
67 | AV* data_out; | |
68 | float *in, *out; | |
69 | int i, error; | |
70 | PPCODE: | |
71 | data.input_frames = (av_len(data_in) + 1) / channels; | |
72 | data.output_frames = data.input_frames * src_ratio + 10; | |
73 | Newx(in, data.input_frames * channels, float); | |
74 | Newx(out, data.output_frames * channels, float); | |
75 | for(i = 0 ; i <= av_len(data_in) ; i++) | |
76 | if(av_exists(data_in, i)) | |
77 | in[i] = SvNV(*av_fetch(data_in, i, 0)); | |
78 | data.data_in = in; | |
79 | data.data_out = out; | |
80 | data.src_ratio = src_ratio; | |
81 | if (error = src_simple(&data, converter_type, channels)) | |
82 | cerror("src_simple"); | |
83 | EXTEND(SP, data.output_frames_gen); | |
84 | for(i = 0 ; i < data.output_frames_gen ; i++) | |
85 | PUSHs(sv_2mortal(newSVnv(data.data_out[i]))); | |
86 | Safefree(in); | |
87 | Safefree(out); | |
88 | ||
89 | SV* | |
90 | new(pkg, converter_type = 0, channels = 2) | |
91 | const char *pkg | |
92 | int converter_type | |
93 | int channels | |
94 | PREINIT: | |
95 | int error; | |
96 | SRC_STATE *state; | |
97 | CODE: | |
98 | state = src_new(converter_type, channels, &error); | |
99 | if(state == NULL) | |
100 | cerror("src_new"); | |
101 | RETVAL = sv_setref_iv(newSV(0), pkg, PTR2IV(state)); | |
102 | OUTPUT: | |
103 | RETVAL | |
104 | ||
105 | void | |
106 | DESTROY(self) | |
107 | SV* self | |
108 | CODE: | |
109 | src_delete(SELF); | |
110 | ||
111 | void | |
112 | process(self, data_in, src_ratio, end_of_input = 0) | |
113 | SV* self | |
114 | AV* data_in | |
115 | double src_ratio | |
116 | int end_of_input | |
117 | PREINIT: | |
118 | SRC_DATA data; | |
119 | AV* data_out; | |
120 | float *in, *out; | |
121 | int i, error; | |
122 | PPCODE: | |
123 | data.input_frames = av_len(data_in) + 1; | |
124 | data.output_frames = data.input_frames * src_ratio + 10; | |
125 | Newx(in, data.input_frames, float); | |
126 | Newx(out, data.output_frames, float); | |
127 | for(i = 0 ; i <= av_len(data_in) ; i++) | |
128 | if(av_exists(data_in, i)) | |
129 | in[i] = SvNV(*av_fetch(data_in, i, 0)); | |
130 | data.data_in = in; | |
131 | data.data_out = out; | |
132 | data.src_ratio = src_ratio; | |
133 | data.end_of_input = end_of_input; | |
134 | if(error = src_process(SELF, &data)) | |
135 | cerror("src_process"); | |
136 | EXTEND(SP, data.output_frames_gen); | |
137 | for(i = 0 ; i < data.output_frames_gen ; i++) | |
138 | PUSHs(sv_2mortal(newSVnv(data.data_out[i]))); | |
139 | ||
140 | void | |
141 | reset(self) | |
142 | SV* self | |
143 | PREINIT: | |
144 | int error; | |
145 | CODE: | |
146 | if(error = src_reset(SELF)) | |
147 | cerror("src_reset"); | |
148 | ||
149 | void | |
150 | set_ratio(self, new_ratio) | |
151 | SV* self | |
152 | double new_ratio | |
153 | PREINIT: | |
154 | int error; | |
155 | CODE: | |
156 | if(error = src_set_ratio(SELF, new_ratio)) | |
157 | cerror("src_set_ratio"); | |
158 | ||
159 | const char* | |
160 | src_get_name(converter_type) | |
161 | int converter_type | |
162 | ||
163 | const char* | |
164 | src_get_description(converter_type) | |
165 | int converter_type |