Jack2  1.9.10
JackAC3Encoder.cpp
00001 /*
00002 Copyright (C) 2006 Jesse Chappell <jesse@essej.net> (AC3Jack)
00003 Copyright (C) 2012 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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     // create interleaved framebuffer for MAX_AC3_CHANNELS
00071         fSampleBuffer = new float[MAX_AC3_CHANNELS * A52_SAMPLES_PER_FRAME];
00072     
00073     // create AC3 buffer
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     // fill and process frame buffers as appropriate
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                         // copy only frames_left more data
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                         // use interleaved version
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                         // push AC3 output to SPDIF ring buffer
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             // write the proper remainder of zero padding (inefficient, should be memsetting)
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                         // copy incoming data into frame buffers without processing
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         // todo, use outsize and not assume the fixed frame size?
00174         int ac3outsize = outsize - SPDIF_HEADER_SIZE;
00175         
00176         buf[0] = 0x72; buf[1] = 0xf8;   /* spdif syncword */
00177         buf[2] = 0x1f; buf[3] = 0x4e;   /* .............. */
00178         buf[4] = 0x01;                  /* AC3 data */
00179         buf[5] = buf[13] & 7;           /* bsmod, stream = 0 */
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                 // just write silence
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                         // write and deinterleave into the two channels
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                         // write silence
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         /* ALERT: signed sign-extension portability !!! */
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         /* ALERT: signed sign-extension portability !!! */
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          * 2 channels = L, R
00259          * 3 channels = L, C, R
00260          * 4 channels = L, R, LS, RS
00261          * 5 ch       = L, C, R,  LS, RS
00262          * 6 ch       = L, C, R,  LS, RS, LFE
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      // Last channel
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 } // end of namespace