00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "asterisk.h"
00036
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
00038
00039
00040 #if defined(__Darwin__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__)
00041 #include <float.h>
00042 #else
00043 #include <values.h>
00044 #endif
00045 #include <limits.h>
00046
00047
00048 #include <libresample.h>
00049
00050 #include "asterisk/module.h"
00051 #include "asterisk/translate.h"
00052
00053 #include "asterisk/slin.h"
00054
00055 #define RESAMPLER_QUALITY 1
00056
00057 #define OUTBUF_SIZE 8096
00058
00059 struct slin16_to_slin8_pvt {
00060 void *resampler;
00061 float resample_factor;
00062 };
00063
00064 struct slin8_to_slin16_pvt {
00065 void *resampler;
00066 float resample_factor;
00067 };
00068
00069 static int slin16_to_slin8_new(struct ast_trans_pvt *pvt)
00070 {
00071 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00072
00073 resamp_pvt->resample_factor = 8000.0 / 16000.0;
00074
00075 if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, resamp_pvt->resample_factor, resamp_pvt->resample_factor)))
00076 return -1;
00077
00078 return 0;
00079 }
00080
00081 static int slin8_to_slin16_new(struct ast_trans_pvt *pvt)
00082 {
00083 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00084
00085 resamp_pvt->resample_factor = 16000.0 / 8000.0;
00086
00087 if (!(resamp_pvt->resampler = resample_open(RESAMPLER_QUALITY, resamp_pvt->resample_factor, resamp_pvt->resample_factor)))
00088 return -1;
00089
00090 return 0;
00091 }
00092
00093 static void slin16_to_slin8_destroy(struct ast_trans_pvt *pvt)
00094 {
00095 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00096
00097 if (resamp_pvt->resampler)
00098 resample_close(resamp_pvt->resampler);
00099 }
00100
00101 static void slin8_to_slin16_destroy(struct ast_trans_pvt *pvt)
00102 {
00103 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00104
00105 if (resamp_pvt->resampler)
00106 resample_close(resamp_pvt->resampler);
00107 }
00108
00109 static int resample_frame(struct ast_trans_pvt *pvt,
00110 void *resampler, float resample_factor, struct ast_frame *f)
00111 {
00112 int total_in_buf_used = 0;
00113 int total_out_buf_used = 0;
00114 int16_t *in_buf = (int16_t *) f->data.ptr;
00115 int16_t *out_buf = pvt->outbuf.i16 + pvt->samples;
00116 float in_buf_f[f->samples];
00117 float out_buf_f[2048];
00118 int res = 0;
00119 int i;
00120
00121 for (i = 0; i < f->samples; i++)
00122 in_buf_f[i] = in_buf[i] * (FLT_MAX / SHRT_MAX);
00123
00124 while (total_in_buf_used < f->samples) {
00125 int in_buf_used, out_buf_used;
00126
00127 out_buf_used = resample_process(resampler, resample_factor,
00128 &in_buf_f[total_in_buf_used], f->samples - total_in_buf_used,
00129 0, &in_buf_used,
00130 &out_buf_f[total_out_buf_used], ARRAY_LEN(out_buf_f) - total_out_buf_used);
00131
00132 if (out_buf_used < 0)
00133 break;
00134
00135 total_out_buf_used += out_buf_used;
00136 total_in_buf_used += in_buf_used;
00137
00138 if (total_out_buf_used == ARRAY_LEN(out_buf_f)) {
00139 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
00140 res = -1;
00141 break;
00142 }
00143 }
00144
00145 for (i = 0; i < total_out_buf_used; i++)
00146 out_buf[i] = out_buf_f[i] * (SHRT_MAX / FLT_MAX);
00147
00148 pvt->samples += total_out_buf_used;
00149 pvt->datalen += (total_out_buf_used * sizeof(int16_t));
00150
00151 return res;
00152 }
00153
00154 static int slin16_to_slin8_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00155 {
00156 struct slin16_to_slin8_pvt *resamp_pvt = pvt->pvt;
00157 void *resampler = resamp_pvt->resampler;
00158 float resample_factor = resamp_pvt->resample_factor;
00159
00160 return resample_frame(pvt, resampler, resample_factor, f);
00161 }
00162
00163 static int slin8_to_slin16_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
00164 {
00165 struct slin8_to_slin16_pvt *resamp_pvt = pvt->pvt;
00166 void *resampler = resamp_pvt->resampler;
00167 float resample_factor = resamp_pvt->resample_factor;
00168
00169 return resample_frame(pvt, resampler, resample_factor, f);
00170 }
00171
00172 static struct ast_translator slin16_to_slin8 = {
00173 .name = "slin16_to_slin8",
00174 .srcfmt = AST_FORMAT_SLINEAR16,
00175 .dstfmt = AST_FORMAT_SLINEAR,
00176 .newpvt = slin16_to_slin8_new,
00177 .destroy = slin16_to_slin8_destroy,
00178 .framein = slin16_to_slin8_framein,
00179 .sample = slin16_sample,
00180 .desc_size = sizeof(struct slin16_to_slin8_pvt),
00181 .buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)),
00182 .buf_size = OUTBUF_SIZE,
00183 };
00184
00185 static struct ast_translator slin8_to_slin16 = {
00186 .name = "slin8_to_slin16",
00187 .srcfmt = AST_FORMAT_SLINEAR,
00188 .dstfmt = AST_FORMAT_SLINEAR16,
00189 .newpvt = slin8_to_slin16_new,
00190 .destroy = slin8_to_slin16_destroy,
00191 .framein = slin8_to_slin16_framein,
00192 .sample = slin8_sample,
00193 .desc_size = sizeof(struct slin8_to_slin16_pvt),
00194 .buffer_samples = (OUTBUF_SIZE / sizeof(int16_t)),
00195 .buf_size = OUTBUF_SIZE,
00196 };
00197
00198 static int unload_module(void)
00199 {
00200 int res = 0;
00201
00202 res |= ast_unregister_translator(&slin16_to_slin8);
00203 res |= ast_unregister_translator(&slin8_to_slin16);
00204
00205 return res;
00206 }
00207
00208 static int load_module(void)
00209 {
00210 int res = 0;
00211
00212 res |= ast_register_translator(&slin16_to_slin8);
00213 res |= ast_register_translator(&slin8_to_slin16);
00214
00215 return AST_MODULE_LOAD_SUCCESS;
00216 }
00217
00218 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SLIN Resampling Codec");