00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackAC3Encoder.h"
00022 #include "JackError.h"
00023 #include <unistd.h>
00024 #include <string.h>
00025 #include <stdio.h>
00026
00027 #define max(x,y) (((x)>(y)) ? (x) : (y))
00028 #define min(x,y) (((x)<(y)) ? (x) : (y))
00029
00030 namespace Jack
00031 {
00032
00033 #ifndef __ppc__
00034
00035 JackAC3Encoder::JackAC3Encoder(const JackAC3EncoderParams& params)
00036 {
00037 aften_set_defaults(&fAftenContext);
00038
00039 fAftenContext.channels = params.channels;
00040 fAftenContext.samplerate = params.sample_rate;
00041 fAftenContext.params.bitrate = params.bitrate;
00042
00043 int acmod = A52_ACMOD_MONO;
00044 int lfe = params.lfe;
00045
00046 switch (params.channels) {
00047
00048 case 1: acmod = A52_ACMOD_MONO; break;
00049 case 2: acmod = A52_ACMOD_STEREO; break;
00050 case 3: acmod = A52_ACMOD_3_0; break;
00051 case 4: acmod = A52_ACMOD_2_2; break;
00052 case 5: acmod = A52_ACMOD_3_2; break;
00053 break;
00054
00055 default:
00056 break;
00057 }
00058
00059 if (lfe) {
00060 fAftenContext.channels += 1;
00061 }
00062
00063 fAftenContext.acmod = acmod;
00064 fAftenContext.lfe = lfe;
00065 fAftenContext.sample_format = A52_SAMPLE_FMT_FLT;
00066 fAftenContext.verbose = 1;
00067
00068 fAftenContext.system.n_threads = 1;
00069
00070
00071 fSampleBuffer = new float[MAX_AC3_CHANNELS * A52_SAMPLES_PER_FRAME];
00072
00073
00074 fAC3Buffer = new unsigned char[A52_MAX_CODED_FRAME_SIZE];
00075 memset(fAC3Buffer, 0, A52_MAX_CODED_FRAME_SIZE);
00076
00077 fZeroBuffer = new unsigned char[SPDIF_FRAME_SIZE];
00078 memset(fZeroBuffer, 0, SPDIF_FRAME_SIZE);
00079
00080 fRingBuffer = jack_ringbuffer_create(32768);
00081
00082 fOutSizeByte = 0;
00083 fFramePos = 0;
00084
00085 fSampleRate = 0;
00086 fByteRate = 0;
00087 }
00088
00089 bool JackAC3Encoder::Init(jack_nframes_t sample_rate)
00090 {
00091 fSampleRate = sample_rate;
00092 fByteRate = fSampleRate * sizeof(short) * 2;
00093 return (aften_encode_init(&fAftenContext) == 0);
00094 }
00095
00096 JackAC3Encoder::~JackAC3Encoder()
00097 {
00098 aften_encode_close(&fAftenContext);
00099
00100 delete [] fSampleBuffer;
00101 delete [] fAC3Buffer;
00102 delete [] fZeroBuffer;
00103
00104 if (fRingBuffer) {
00105 jack_ringbuffer_free(fRingBuffer);
00106 }
00107 }
00108
00109 void JackAC3Encoder::Process(float** inputs_buffer, float** outputs_buffer, int nframes)
00110 {
00111
00112 jack_nframes_t frames_left = A52_SAMPLES_PER_FRAME - fFramePos;
00113 jack_nframes_t offset = 0;
00114
00115 while (offset < nframes)
00116 {
00117 if ((nframes - offset) >= frames_left) {
00118
00119
00120 jack_nframes_t pos = fFramePos * fAftenContext.channels;
00121 for (jack_nframes_t spos = offset; spos < offset + frames_left; ++spos) {
00122 for (size_t i = 0; i < fAftenContext.channels; ++i) {
00123 fSampleBuffer[pos + i] = inputs_buffer[i][spos];
00124 }
00125 pos += fAftenContext.channels;
00126 }
00127
00128
00129 int res = aften_encode_frame(&fAftenContext, fAC3Buffer + SPDIF_HEADER_SIZE, fSampleBuffer);
00130 if (res < 0) {
00131 jack_error("aften_encode_frame error !!");
00132 return;
00133 }
00134
00135 fOutSizeByte = res;
00136
00137 FillSpdifHeader(fAC3Buffer, fOutSizeByte + SPDIF_HEADER_SIZE);
00138
00139
00140 float calc_ac3byterate = (fOutSizeByte * fSampleRate / (float) A52_SAMPLES_PER_FRAME);
00141 jack_nframes_t silencebytes = (jack_nframes_t) (fOutSizeByte * (fByteRate / calc_ac3byterate)) - fOutSizeByte - SPDIF_HEADER_SIZE;
00142
00143 jack_ringbuffer_write(fRingBuffer, (const char *)fAC3Buffer, fOutSizeByte + SPDIF_HEADER_SIZE);
00144
00145
00146 jack_ringbuffer_write(fRingBuffer, (const char *)fZeroBuffer, silencebytes);
00147
00148 offset += frames_left;
00149 frames_left = A52_SAMPLES_PER_FRAME;
00150 fFramePos = 0;
00151
00152 } else {
00153
00154
00155 jack_nframes_t pos = fFramePos * fAftenContext.channels;
00156 for (jack_nframes_t spos = offset; spos < nframes; ++spos) {
00157 for (size_t i = 0; i < fAftenContext.channels; ++i) {
00158 fSampleBuffer[pos + i] = inputs_buffer[i][spos];
00159 }
00160 pos += fAftenContext.channels;
00161 }
00162
00163 fFramePos += (nframes - offset);
00164 offset += (nframes-offset);
00165 }
00166 }
00167
00168 Output2Driver(outputs_buffer, nframes);
00169 }
00170
00171 void JackAC3Encoder::FillSpdifHeader(unsigned char* buf, int outsize)
00172 {
00173
00174 int ac3outsize = outsize - SPDIF_HEADER_SIZE;
00175
00176 buf[0] = 0x72; buf[1] = 0xf8;
00177 buf[2] = 0x1f; buf[3] = 0x4e;
00178 buf[4] = 0x01;
00179 buf[5] = buf[13] & 7;
00180 buf[6] = (ac3outsize << 3) & 0xff;
00181 buf[7] = (ac3outsize >> 5) & 0xff;
00182
00183 #if !IS_BIGENDIAN
00184 swab(buf+SPDIF_HEADER_SIZE, buf + SPDIF_HEADER_SIZE, ac3outsize);
00185 #endif
00186 }
00187
00188 int JackAC3Encoder::Output2Driver(float** outputs, jack_nframes_t nframes)
00189 {
00190 int wrotebytes = 0;
00191 jack_nframes_t nframes_left = nframes;
00192
00193 if (jack_ringbuffer_read_space(fRingBuffer) == 0) {
00194
00195
00196 memset(outputs[0], 0, nframes * sizeof(jack_default_audio_sample_t));
00197 memset(outputs[1], 0, nframes * sizeof(jack_default_audio_sample_t));
00198
00199 } else {
00200
00201 jack_ringbuffer_data_t rb_data[2];
00202
00203 jack_ringbuffer_get_read_vector(fRingBuffer, rb_data);
00204
00205 while (nframes_left > 0 && rb_data[0].len > 4) {
00206
00207 jack_nframes_t towrite_frames = (rb_data[0].len) / (sizeof(short) * 2);
00208 towrite_frames = min(towrite_frames, nframes_left);
00209
00210
00211 #if 1
00212 sample_move_dS_s16(outputs[0] + (nframes - nframes_left), (char *) rb_data[0].buf, towrite_frames, sizeof(short) * 2);
00213 sample_move_dS_s16(outputs[1] + (nframes - nframes_left), (char *) rb_data[0].buf + sizeof(short), towrite_frames, sizeof(short) * 2);
00214 #else
00215 sample_move_dS_s16_24ph(outputs[0] + (nframes - nframes_left), (char *) rb_data[0].buf, towrite_frames, sizeof(short) * 2);
00216 sample_move_dS_s16_24ph(outputs[1] + (nframes - nframes_left), (char *) rb_data[0].buf + sizeof(short), towrite_frames, sizeof(short) * 2);
00217 #endif
00218 wrotebytes = towrite_frames * sizeof(short) * 2;
00219 nframes_left -= towrite_frames;
00220
00221 jack_ringbuffer_read_advance(fRingBuffer, wrotebytes);
00222 jack_ringbuffer_get_read_vector(fRingBuffer, rb_data);
00223 }
00224
00225 if (nframes_left > 0) {
00226
00227 memset(outputs[0] + (nframes - nframes_left), 0, (nframes_left) * sizeof(jack_default_audio_sample_t));
00228 memset(outputs[1] + (nframes - nframes_left), 0, (nframes_left) * sizeof(jack_default_audio_sample_t));
00229 }
00230 }
00231
00232 return wrotebytes;
00233 }
00234
00235 void JackAC3Encoder::sample_move_dS_s16(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip)
00236 {
00237
00238 while (nsamples--) {
00239 *dst = (*((short *) src)) / SAMPLE_MAX_16BIT;
00240 dst++;
00241 src += src_skip;
00242 }
00243 }
00244
00245 void JackAC3Encoder::sample_move_dS_s16_24ph(jack_default_audio_sample_t* dst, char *src, jack_nframes_t nsamples, unsigned long src_skip)
00246 {
00247
00248 while (nsamples--) {
00249 *dst = (((int)(*((short *) src))) << 8) / SAMPLE_MAX_24BIT;
00250 dst++;
00251 src += src_skip;
00252 }
00253 }
00254
00255 void JackAC3Encoder::GetChannelName(const char* name, const char* alias, char* portname, int channel)
00256 {
00257
00258
00259
00260
00261
00262
00263
00264
00265 const char* AC3_name = "";
00266
00267 switch (channel) {
00268
00269 case 0:
00270 AC3_name = "AC3_1_Left";
00271 break;
00272
00273 case 1:
00274 if (fAftenContext.channels == 2 || fAftenContext.channels == 4) {
00275 AC3_name = "AC3_2_Right";
00276 } else {
00277 AC3_name = "AC3_2_Center";
00278 }
00279 break;
00280
00281 case 2:
00282 if (fAftenContext.channels == 4) {
00283 AC3_name = "AC3_3_LeftSurround";
00284 } else {
00285 AC3_name = "AC3_3_Right";
00286 }
00287 break;
00288
00289 case 3:
00290 if (fAftenContext.channels == 4) {
00291 AC3_name = "AC3_4_RightSurround";
00292 } else {
00293 AC3_name = "AC3_4_LeftSurround";
00294 }
00295 break;
00296
00297 case 4:
00298 if (fAftenContext.channels > 4) {
00299 AC3_name = "AC3_5_RightSurround";
00300 }
00301 break;
00302
00303 default:
00304 break;
00305 }
00306
00307
00308 if (fAftenContext.lfe && (channel == fAftenContext.channels - 1)) {
00309 sprintf(portname, "%s:%s:AC3_%d_LFE", name, alias, fAftenContext.channels);
00310 } else {
00311 sprintf(portname, "%s:%s:%s", name, alias, AC3_name);
00312 }
00313 }
00314
00315 #endif
00316
00317 }