static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ int i; int vendorlen=oggpack_read(opb,32); if(vendorlen<0)goto err_out; if(vendorlen>opb->storage-8)goto err_out; vc->vendor=_ogg_calloc(vendorlen+1,1); _v_readstring(opb,vc->vendor,vendorlen); i=oggpack_read(opb,32); if(i<0)goto err_out; if(i>((opb->storage-oggpack_bytes(opb))>>2))goto err_out; vc->comments=i; vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); for(i=0;i<vc->comments;i++){ int len=oggpack_read(opb,32); if(len<0)goto err_out; if(len>opb->storage-oggpack_bytes(opb))goto err_out; vc->comment_lengths[i]=len; vc->user_comments[i]=_ogg_calloc(len+1,1); _v_readstring(opb,vc->user_comments[i],len); } if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ return(0); err_out: vorbis_comment_clear(vc); return(OV_EBADHEADER); }
/* build the comment header packet from the passed metadata */ int theora_encode_comment(theora_comment *tc, ogg_packet *op) { const char *vendor = theora_version_string(); const int vendor_length = strlen(vendor); oggpack_buffer *opb; #ifndef LIBOGG2 opb = _ogg_malloc(sizeof(oggpack_buffer)); oggpackB_writeinit(opb); #else opb = _ogg_malloc(oggpack_buffersize()); oggpackB_writeinit(opb, ogg_buffer_create()); #endif oggpackB_write(opb, 0x81, 8); _tp_writebuffer(opb, "theora", 6); _tp_writelsbint(opb, vendor_length); _tp_writebuffer(opb, vendor, vendor_length); _tp_writelsbint(opb, tc->comments); if(tc->comments){ int i; for(i=0;i<tc->comments;i++){ if(tc->user_comments[i]){ _tp_writelsbint(opb,tc->comment_lengths[i]); _tp_writebuffer(opb,tc->user_comments[i],tc->comment_lengths[i]); }else{ oggpackB_write(opb,0,32); } } } op->bytes=oggpack_bytes(opb); #ifndef LIBOGG2 /* So we're expecting the application will free this? */ op->packet=_ogg_malloc(oggpack_bytes(opb)); memcpy(op->packet, oggpack_get_buffer(opb), oggpack_bytes(opb)); oggpack_writeclear(opb); #else op->packet = oggpack_writebuffer(opb); /* When the application puts op->packet into a stream_state object, it becomes the property of libogg2's internal memory management. */ #endif _ogg_free(opb); op->b_o_s=0; op->e_o_s=0; op->packetno=0; op->granulepos=0; return (0); }
static int _commentheader_out(vcedit_state *state, ogg_packet *op) { vorbis_comment *vc = state->vc; char *vendor = state->vendor; oggpack_buffer opb; oggpack_writeinit(&opb); if (state->oggtype == VCEDIT_IS_OGGVORBIS) { /* preamble */ oggpack_write(&opb,0x03,8); _v_writestring(&opb,"vorbis", 6); } /* vendor */ oggpack_write(&opb,strlen(vendor),32); _v_writestring(&opb,vendor, strlen(vendor)); /* comments */ oggpack_write(&opb,vc->comments,32); if(vc->comments){ int i; for(i=0;i<vc->comments;i++){ if(vc->user_comments[i]){ oggpack_write(&opb,vc->comment_lengths[i],32); _v_writestring(&opb,vc->user_comments[i], vc->comment_lengths[i]); }else{ oggpack_write(&opb,0,32); } } } oggpack_write(&opb,1,1); op->packet = _ogg_malloc(oggpack_bytes(&opb)); memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes=oggpack_bytes(&opb); op->b_o_s=0; op->e_o_s=0; op->granulepos=0; if (state->oggtype == VCEDIT_IS_OGGVORBIS) { op->packetno = 1; } oggpack_writeclear(&opb); return 0; }
/* decides between modes, dispatches to the appropriate mapping. */ int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ int ret; vb->glue_bits=0; vb->time_bits=0; vb->floor_bits=0; vb->res_bits=0; /* first things first. Make sure encode is ready */ oggpack_reset(&vb->opb); /* we only have one mapping type (0), and we let the mapping code itself figure out what soft mode to use. This allows easier bitrate management */ if((ret=_mapping_P[0]->forward(vb))) return(ret); if(op){ if(vorbis_bitrate_managed(vb)) /* The app is using a bitmanaged mode... but not using the bitrate management interface. */ return(OV_EINVAL); op->packet=oggpack_get_buffer(&vb->opb); op->bytes=oggpack_bytes(&vb->opb); op->b_o_s=0; op->e_o_s=vb->eofflag; op->granulepos=vb->granulepos; op->packetno=vb->sequence; /* for sake of completeness */ } return(0); }
TarkinError _analysis_packetout (TarkinStream * s, uint32_t layer_id, uint32_t comp) { ogg_packet op; oggpack_buffer opb; uint8_t *data; uint32_t data_len; int i; data = s->layer[layer_id].packet[comp].data; data_len = s->layer[layer_id].packet[comp].data_len; oggpack_writeinit (&opb); oggpack_write (&opb, 0, 8); /* No feature flags for now */ oggpack_write (&opb, layer_id, 12); oggpack_write (&opb, comp, 12); for (i = 0; i < data_len; i++) oggpack_write (&opb, *(data + i), 8); op.b_o_s = 0; op.e_o_s = data_len ? 0 : 1; op.granulepos = 0; op.bytes = oggpack_bytes (&opb) + 4; op.packet = opb.buffer; #ifdef DBG_OGG printf ("dbg_ogg: writing packet layer %d, comp %d, data_len %d %s\n", layer_id, comp, data_len, op.e_o_s ? "eos" : ""); #endif s->layer[layer_id].packet[comp].data_len = 0; /* so direct call => eos */ return (s->packet_out (s, &op)); }
static PyObject * py_ogg_oggpack_bytes(PyObject *self, PyObject *args) { long c_out; int size; oggpack_buffer * b; PyArg_ParseTuple(args, "s#", &b, &size); c_out = oggpack_bytes(b); return Py_BuildValue("l", c_out); };
int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op){ oggpack_buffer opb; oggpack_writeinit(&opb); if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; op->packet = _ogg_malloc(oggpack_bytes(&opb)); memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes=oggpack_bytes(&opb); op->b_o_s=0; op->e_o_s=0; op->granulepos=0; return 0; }
int BURGERCALL vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op){ oggpack_buffer opb; oggpack_writeinit(&opb); if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; op->packet = static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes=oggpack_bytes(&opb); op->b_o_s=0; op->e_o_s=0; op->granulepos=0; return 0; }
int tarkin_comment_header_out(TarkinComment *vc, ogg_packet *op) { oggpack_buffer opb; oggpack_writeinit(&opb); if(_tarkin_pack_comment(&opb,vc)) return -TARKIN_NOT_IMPLEMENTED; op->packet = MALLOC(oggpack_bytes(&opb)); memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes=oggpack_bytes(&opb); op->b_o_s=0; op->e_o_s=0; op->granulepos=0; return 0; }
/* build the comment header packet from the passed metadata */ int theora_encode_comment(theora_comment *tc, ogg_packet *op) { const char *vendor = theora_version_string(); const int vendor_length = strlen(vendor); oggpack_buffer *opb; opb = _ogg_malloc(sizeof(oggpack_buffer)); oggpackB_writeinit(opb); oggpackB_write(opb, 0x81, 8); _tp_writebuffer(opb, "theora", 6); _tp_writelsbint(opb, vendor_length); _tp_writebuffer(opb, vendor, vendor_length); _tp_writelsbint(opb, tc->comments); if(tc->comments){ int i; for(i=0;i<tc->comments;i++){ if(tc->user_comments[i]){ _tp_writelsbint(opb,tc->comment_lengths[i]); _tp_writebuffer(opb,tc->user_comments[i],tc->comment_lengths[i]); }else{ oggpackB_write(opb,0,32); } } } op->bytes=oggpack_bytes(opb); /* So we're expecting the application will free this? */ op->packet=_ogg_malloc(oggpack_bytes(opb)); memcpy(op->packet, oggpack_get_buffer(opb), oggpack_bytes(opb)); oggpack_writeclear(opb); _ogg_free(opb); op->b_o_s=0; op->e_o_s=0; op->packetno=0; op->granulepos=0; return (0); }
static int _commentheader_out(vorbis_comment * vc, char *vendor, ogg_packet * op) { oggpack_buffer opb; oggpack_writeinit(&opb); /* preamble */ oggpack_write(&opb, 0x03, 8); _v_writestring(&opb, "vorbis", 6); /* vendor */ oggpack_write(&opb, strlen(vendor), 32); _v_writestring(&opb, vendor, strlen(vendor)); /* comments */ oggpack_write(&opb, vc->comments, 32); if (vc->comments) { int i; for (i = 0; i < vc->comments; i++) { if (vc->user_comments[i]) { oggpack_write(&opb, vc->comment_lengths[i], 32); _v_writestring(&opb, vc->user_comments[i], vc->comment_lengths[i]); } else { oggpack_write(&opb, 0, 32); } } } oggpack_write(&opb, 1, 1); op->packet = _ogg_malloc(oggpack_bytes(&opb)); memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); op->bytes = oggpack_bytes(&opb); op->b_o_s = 0; op->e_o_s = 0; op->granulepos = 0; return 0; }
int vorbis_analysis_headerout(vorbis_dsp_state *v, ogg_packet *op_code) { int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; private_state *b=v->backend_state; if(!b){ ret=OV_EFAULT; goto err_out; } oggpack_writeinit(&opb); /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)_ogg_free(b->header2); b->header2=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; oggpack_writeclear(&opb); return(0); err_out: oggpack_writeclear(&opb); memset(op_code,0,sizeof(*op_code)); if(b->header2)_ogg_free(b->header2); b->header2=NULL; return(ret); }
/* * Class: org_tritonus_lowlevel_ogg_Buffer * Method: bytes * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_ogg_Buffer_bytes (JNIEnv* env, jobject obj) { oggpack_buffer* handle; int nReturn; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_bytes(): begin\n"); } handle = getHandle(env, obj); nReturn = oggpack_bytes(handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_bytes(): end\n"); } return nReturn; }
static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ int vendorlen; vendorlen=oggpack_read(opb,32); if(vendorlen<0)goto err_out; if(vendorlen>opb->storage-oggpack_bytes(opb))goto err_out; vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); if(vc->vendor==NULL)goto err_out; _v_readstring(opb,vc->vendor,vendorlen); vc->comments=0; /* ROCKBOX: the meat of this function was deleted as we don't need it */ return(0); err_out: vorbis_comment_clear(vc); return(OV_EBADHEADER); }
/* decides between modes, dispatches to the appropriate mapping. */ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){ vorbis_dsp_state *vd=vb->vd; backend_lookup_state *b=vd->backend_state; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; int type,ret; int mode=0; vb->glue_bits=0; vb->time_bits=0; vb->floor_bits=0; vb->res_bits=0; /* first things first. Make sure encode is ready */ oggpack_reset(&vb->opb); /* Encode the packet type */ oggpack_write(&vb->opb,0,1); /* currently lazy. Short block dispatches to 0, long to 1. */ if(vb->W &&ci->modes>1)mode=1; type=ci->map_type[ci->mode_param[mode]->mapping]; vb->mode=mode; /* Encode frame mode, pre,post windowsize, then dispatch */ oggpack_write(&vb->opb,mode,b->modebits); if(vb->W){ oggpack_write(&vb->opb,vb->lW,1); oggpack_write(&vb->opb,vb->nW,1); /*fprintf(stderr,"*"); }else{ fprintf(stderr,".");*/ } if((ret=_mapping_P[type]->forward(vb,b->mode[mode]))) return(ret); /* set up the packet wrapper */ op->packet=oggpack_get_buffer(&vb->opb); op->bytes=oggpack_bytes(&vb->opb); op->b_o_s=0; op->e_o_s=vb->eofflag; op->granulepos=vb->granulepos; op->packetno=vb->sequence; /* for sake of completeness */ return(0); }
static bool write_comments (vcedit_state *s, ogg_packet *packet) { oggpack_buffer opb; size_t len; int i; ogg_packet_init (packet, NULL, 0); oggpack_writeinit (&opb); /* preamble */ oggpack_write (&opb, 0x03, 8); _v_writestring (&opb, "vorbis", 6); /* vendor */ len = strlen (s->vendor); oggpack_write (&opb, len, 32); _v_writestring (&opb, s->vendor, len); /* comments */ oggpack_write (&opb, s->vc.comments, 32); for (i = 0; i < s->vc.comments; i++) if (!s->vc.user_comments[i]) oggpack_write (&opb, 0, 32); else { oggpack_write (&opb, s->vc.comment_lengths[i], 32); _v_writestring (&opb, s->vc.user_comments[i], s->vc.comment_lengths[i]); } oggpack_write (&opb, 1, 1); packet->bytes = oggpack_bytes (&opb); packet->packet = _ogg_malloc (packet->bytes); if (!packet->packet) return false; memcpy (packet->packet, opb.buffer, packet->bytes); oggpack_writeclear (&opb); return true; }
static int _tarkin_pack_layer_desc (oggpack_buffer * opb, TarkinInfo * vi) { int i; TarkinVideoLayer *layer; #ifdef DBG_OGG printf ("dbg_ogg: Putting out layers description:\n"); #endif oggpack_write (opb, 0x05, 8); _v_writestring (opb, "tarkin", 6); for (i = 0; i < vi->n_layers; i++) { layer = vi->layer + i; oggpack_write (opb, layer->desc.width, 32); oggpack_write (opb, layer->desc.height, 32); oggpack_write (opb, layer->desc.a_moments, 32); oggpack_write (opb, layer->desc.s_moments, 32); oggpack_write (opb, layer->desc.frames_per_buf, 32); oggpack_write (opb, layer->desc.bitstream_len, 32); oggpack_write (opb, layer->desc.format, 32); #ifdef DBG_OGG printf (" res. %dx%d, format %d, a_m %d, s_m %d, fpb %d\n", layer->desc.width, layer->desc.height, layer->desc.format, layer->desc.a_moments, layer->desc.s_moments, layer->desc.frames_per_buf); #endif } oggpack_write (opb, 1, 1); #ifdef DBG_OGG printf (" wrote %ld bytes.\n", oggpack_bytes (opb)); #endif return (0); }
void rebuilder::rebuild_id_header( int channels, int rate, int blocksize_short, int blocksize_long, ogg_packet_holder & packet) { // Identification header oggpack_buffer opb; oggpack_writeinit(&opb); // Preamble oggpack_write(&opb, 0x01, 8); oggpack_write_string(&opb, "vorbis"); // Basic information about the stream. oggpack_write(&opb, 0x00, 32); oggpack_write(&opb, channels, 8); oggpack_write(&opb, rate, 32); // Bitrate upper, nominal and lower. // All are optional and we do not provide them. oggpack_write(&opb, 0, 32); oggpack_write(&opb, 0, 32); oggpack_write(&opb, 0, 32); oggpack_write(&opb, ilog2(blocksize_short), 4); oggpack_write(&opb, ilog2(blocksize_long), 4); oggpack_write(&opb, 1, 1); CHECK(oggpack_writecheck(&opb) == 0); packet.assign(opb.buffer, oggpack_bytes(&opb)); packet->b_o_s = 1; packet->e_o_s = 0; packet->granulepos = 0; packet->packetno = 0; oggpack_writeclear(&opb); }
int BURGERCALL vorbis_analysis_headerout(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code){ int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; backend_lookup_state *b=static_cast<backend_lookup_state *>(v->backend_state); if(!b){ ret=OV_EFAULT; goto err_out; } /* first header packet **********************************************/ oggpack_writeinit(&opb); if(_vorbis_pack_info(&opb,vi))goto err_out; /* build the packet */ if(b->header)DeallocAPointer(b->header); b->header=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header,opb.buffer,oggpack_bytes(&opb)); op->packet=b->header; op->bytes=oggpack_bytes(&opb); op->b_o_s=1; op->e_o_s=0; op->granulepos=0; /* second header packet (comments) **********************************/ oggpack_reset(&opb); if(_vorbis_pack_comment(&opb,vc))goto err_out; if(b->header1)DeallocAPointer(b->header1); b->header1=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header1,opb.buffer,oggpack_bytes(&opb)); op_comm->packet=b->header1; op_comm->bytes=oggpack_bytes(&opb); op_comm->b_o_s=0; op_comm->e_o_s=0; op_comm->granulepos=0; /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)DeallocAPointer(b->header2); b->header2=static_cast<Word8 *>(AllocAPointer(oggpack_bytes(&opb))); FastMemCpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; oggpack_writeclear(&opb); return(0); err_out: oggpack_writeclear(&opb); FastMemSet(op,0,sizeof(*op)); FastMemSet(op_comm,0,sizeof(*op_comm)); FastMemSet(op_code,0,sizeof(*op_code)); if(b->header)DeallocAPointer(b->header); if(b->header1)DeallocAPointer(b->header1); if(b->header2)DeallocAPointer(b->header2); b->header=NULL; b->header1=NULL; b->header2=NULL; return(ret); }
JNIEXPORT jlong JNICALL Java_org_echocat_jogg_OggPackBufferJNI_bytes (JNIEnv *env, jclass thisClass, jlong handle) { return (jlong) oggpack_bytes((oggpack_buffer*) handle); }
int vorbis_analysis_headerout(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code){ int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; private_state *b=v->backend_state; if(!b){ ret=OV_EFAULT; goto err_out; } /* first header packet **********************************************/ oggpack_writeinit(&opb); if(_vorbis_pack_info(&opb,vi))goto err_out; /* build the packet */ if(b->header)_ogg_free(b->header); b->header=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); op->packet=b->header; op->bytes=oggpack_bytes(&opb); op->b_o_s=1; op->e_o_s=0; op->granulepos=0; op->packetno=0; /* second header packet (comments) **********************************/ oggpack_reset(&opb); if(_vorbis_pack_comment(&opb,vc))goto err_out; if(b->header1)_ogg_free(b->header1); b->header1=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); op_comm->packet=b->header1; op_comm->bytes=oggpack_bytes(&opb); op_comm->b_o_s=0; op_comm->e_o_s=0; op_comm->granulepos=0; op_comm->packetno=1; /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)_ogg_free(b->header2); b->header2=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; op_code->packetno=2; oggpack_writeclear(&opb); return(0); err_out: memset(op,0,sizeof(*op)); memset(op_comm,0,sizeof(*op_comm)); memset(op_code,0,sizeof(*op_code)); if(b){ oggpack_writeclear(&opb); if(b->header)_ogg_free(b->header); if(b->header1)_ogg_free(b->header1); if(b->header2)_ogg_free(b->header2); b->header=NULL; b->header1=NULL; b->header2=NULL; } return(ret); }
static int mapping0_forward(vorbis_block *vb){ vorbis_dsp_state *vd=vb->vd; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; private_state *b=vb->vd->backend_state; vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; int n=vb->pcmend; int i,j,k; int *nonzero = alloca(sizeof(*nonzero)*vi->channels); float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); int **ilogmaskch= _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch)); int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); float global_ampmax=vbi->ampmax; float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels); int blocktype=vbi->blocktype; int modenumber=vb->W; vorbis_info_mapping0 *info=ci->map_param[modenumber]; vorbis_look_psy *psy_look= b->psy+blocktype+(vb->W?2:0); vb->mode=modenumber; for(i=0;i<vi->channels;i++){ float scale=4.f/n; float scale_dB; float *pcm =vb->pcm[i]; float *logfft =pcm; gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); scale_dB=todB(&scale); #if 0 if(vi->channels==2) if(i==0) _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2); else _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2); #endif /* window the PCM data */ _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); #if 0 if(vi->channels==2) if(i==0) _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2); else _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2); #endif /* transform the PCM data */ /* only MDCT right now.... */ mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]); /* FFT yields more accurate tonal estimation (not phase sensitive) */ drft_forward(&b->fft_look[vb->W],pcm); logfft[0]=scale_dB+todB(pcm); local_ampmax[i]=logfft[0]; for(j=1;j<n-1;j+=2){ float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1]; temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp); if(temp>local_ampmax[i])local_ampmax[i]=temp; } if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; #if 0 if(vi->channels==2) if(i==0) _analysis_output("fftL",seq,logfft,n/2,1,0,0); else _analysis_output("fftR",seq,logfft,n/2,1,0,0); #endif } { float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise)); float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone)); for(i=0;i<vi->channels;i++){ /* the encoder setup assumes that all the modes used by any specific bitrate tweaking use the same floor */ int submap=info->chmuxlist[i]; /* the following makes things clearer to *me* anyway */ float *mdct =gmdct[i]; float *logfft =vb->pcm[i]; float *logmdct =logfft+n/2; float *logmask =logfft; vb->mode=modenumber; floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts)); memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS); for(j=0;j<n/2;j++) logmdct[j]=todB(mdct+j); #if 0 if(vi->channels==2){ if(i==0) _analysis_output("mdctL",seq,logmdct,n/2,1,0,0); else _analysis_output("mdctR",seq,logmdct,n/2,1,0,0); }else{ _analysis_output("mdct",seq,logmdct,n/2,1,0,0); } #endif /* first step; noise masking. Not only does 'noise masking' give us curves from which we can decide how much resolution to give noise parts of the spectrum, it also implicitly hands us a tonality estimate (the larger the value in the 'noise_depth' vector, the more tonal that area is) */ _vp_noisemask(psy_look, logmdct, noise); /* noise does not have by-frequency offset bias applied yet */ #if 0 if(vi->channels==2){ if(i==0) _analysis_output("noiseL",seq,noise,n/2,1,0,0); else _analysis_output("noiseR",seq,noise,n/2,1,0,0); } #endif /* second step: 'all the other crap'; all the stuff that isn't computed/fit for bitrate management goes in the second psy vector. This includes tone masking, peak limiting and ATH */ _vp_tonemask(psy_look, logfft, tone, global_ampmax, local_ampmax[i]); #if 0 if(vi->channels==2){ if(i==0) _analysis_output("toneL",seq,tone,n/2,1,0,0); else _analysis_output("toneR",seq,tone,n/2,1,0,0); } #endif /* third step; we offset the noise vectors, overlay tone masking. We then do a floor1-specific line fit. If we're performing bitrate management, the line fit is performed multiple times for up/down tweakage on demand. */ _vp_offset_and_mix(psy_look, noise, tone, 1, logmask); #if 0 if(vi->channels==2){ if(i==0) _analysis_output("mask1L",seq,logmask,n/2,1,0,0); else _analysis_output("mask1R",seq,logmask,n/2,1,0,0); } #endif /* this algorithm is hardwired to floor 1 for now; abort out if we're *not* floor1. This won't happen unless someone has broken the encode setup lib. Guard it anyway. */ if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); floor_posts[i][PACKETBLOBS/2]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* are we managing bitrate? If so, perform two more fits for later rate tweaking (fits represent hi/lo) */ if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ /* higher rate by way of lower noise curve */ _vp_offset_and_mix(psy_look, noise, tone, 2, logmask); #if 0 if(vi->channels==2){ if(i==0) _analysis_output("mask2L",seq,logmask,n/2,1,0,0); else _analysis_output("mask2R",seq,logmask,n/2,1,0,0); } #endif floor_posts[i][PACKETBLOBS-1]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* lower rate by way of higher noise curve */ _vp_offset_and_mix(psy_look, noise, tone, 0, logmask); #if 0 if(vi->channels==2) if(i==0) _analysis_output("mask0L",seq,logmask,n/2,1,0,0); else _analysis_output("mask0R",seq,logmask,n/2,1,0,0); #endif floor_posts[i][0]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], logmdct, logmask); /* we also interpolate a range of intermediate curves for intermediate rates */ for(k=1;k<PACKETBLOBS/2;k++) floor_posts[i][k]= floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][0], floor_posts[i][PACKETBLOBS/2], k*65536/(PACKETBLOBS/2)); for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++) floor_posts[i][k]= floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][PACKETBLOBS/2], floor_posts[i][PACKETBLOBS-1], (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); } } } vbi->ampmax=global_ampmax; /* the next phases are performed once for vbr-only and PACKETBLOB times for bitrate managed modes. 1) encode actual mode being used 2) encode the floor for each channel, compute coded mask curve/res 3) normalize and couple. 4) encode residue 5) save packet bytes to the packetblob vector */ /* iterate over the many masking curve fits we've created */ { float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels); float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); int **sortindex=alloca(sizeof(*sortindex)*vi->channels); float **mag_memo; int **mag_sort; if(info->coupling_steps){ mag_memo=_vp_quantize_couple_memo(vb, &ci->psy_g_param, psy_look, info, gmdct); mag_sort=_vp_quantize_couple_sort(vb, psy_look, info, mag_memo); } memset(sortindex,0,sizeof(*sortindex)*vi->channels); if(psy_look->vi->normal_channel_p){ for(i=0;i<vi->channels;i++){ float *mdct =gmdct[i]; sortindex[i]=alloca(sizeof(**sortindex)*n/2); _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]); } } for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); k++){ /* start out our new packet blob with packet type and mode */ /* Encode the packet type */ oggpack_write(&vb->opb,0,1); /* Encode the modenumber */ /* Encode frame mode, pre,post windowsize, then dispatch */ oggpack_write(&vb->opb,modenumber,b->modebits); if(vb->W){ oggpack_write(&vb->opb,vb->lW,1); oggpack_write(&vb->opb,vb->nW,1); } /* encode floor, compute masking curve, sep out residue */ for(i=0;i<vi->channels;i++){ int submap=info->chmuxlist[i]; float *mdct =gmdct[i]; float *res =vb->pcm[i]; int *ilogmask=ilogmaskch[i]= _vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); nonzero[i]=floor1_encode(vb,b->flr[info->floorsubmap[submap]], floor_posts[i][k], ilogmask); #if 0 { char buf[80]; sprintf(buf,"maskI%c%d",i?'R':'L',k); float work[n/2]; for(j=0;j<n/2;j++) work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]; _analysis_output(buf,seq,work,n/2,1,1,0); } #endif _vp_remove_floor(psy_look, mdct, ilogmask, res, ci->psy_g_param.sliding_lowpass[vb->W][k]); _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]); #if 0 { char buf[80]; float work[n/2]; for(j=0;j<n/2;j++) work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]*(res+n/2)[j]; sprintf(buf,"resI%c%d",i?'R':'L',k); _analysis_output(buf,seq,work,n/2,1,1,0); } #endif } /* our iteration is now based on masking curve, not prequant and coupling. Only one prequant/coupling step */ /* quantize/couple */ /* incomplete implementation that assumes the tree is all depth one, or no tree at all */ if(info->coupling_steps){ _vp_couple(k, &ci->psy_g_param, psy_look, info, vb->pcm, mag_memo, mag_sort, ilogmaskch, nonzero, ci->psy_g_param.sliding_lowpass[vb->W][k]); } /* classify and encode by submap */ for(i=0;i<info->submaps;i++){ int ch_in_bundle=0; long **classifications; int resnum=info->residuesubmap[i]; for(j=0;j<vi->channels;j++){ if(info->chmuxlist[j]==i){ zerobundle[ch_in_bundle]=0; if(nonzero[j])zerobundle[ch_in_bundle]=1; res_bundle[ch_in_bundle]=vb->pcm[j]; couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2; } } classifications=_residue_P[ci->residue_type[resnum]]-> class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); _residue_P[ci->residue_type[resnum]]-> forward(vb,b->residue[resnum], couple_bundle,NULL,zerobundle,ch_in_bundle,classifications); } /* ok, done encoding. Mark this protopacket and prepare next. */ oggpack_writealign(&vb->opb); vbi->packetblob_markers[k]=oggpack_bytes(&vb->opb); } } #if 0 seq++; total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; #endif return(0); }
TarkinError tarkin_analysis_headerout (TarkinStream * v, TarkinComment * vc, ogg_packet * op, ogg_packet * op_comm, ogg_packet * op_code) { int ret = -TARKIN_NOT_IMPLEMENTED; TarkinInfo *vi; oggpack_buffer opb; tarkin_header_store *b = &v->headers; vi = v->ti; /* first header packet ********************************************* */ oggpack_writeinit (&opb); if (_tarkin_pack_info (&opb, vi)) goto err_out; /* build the packet */ if (b->header) FREE (b->header); b->header = MALLOC (oggpack_bytes (&opb)); memcpy (b->header, opb.buffer, oggpack_bytes (&opb)); op->packet = b->header; op->bytes = oggpack_bytes (&opb); op->b_o_s = 1; op->e_o_s = 0; op->granulepos = 0; /* second header packet (comments) ********************************* */ oggpack_reset (&opb); if (_tarkin_pack_comment (&opb, vc)) goto err_out; if (b->header1) FREE (b->header1); b->header1 = MALLOC (oggpack_bytes (&opb)); memcpy (b->header1, opb.buffer, oggpack_bytes (&opb)); op_comm->packet = b->header1; op_comm->bytes = oggpack_bytes (&opb); op_comm->b_o_s = 0; op_comm->e_o_s = 0; op_comm->granulepos = 0; /* third header packet (modes/codebooks) *************************** */ oggpack_reset (&opb); if (_tarkin_pack_layer_desc (&opb, vi)) goto err_out; if (b->header2) FREE (b->header2); b->header2 = MALLOC (oggpack_bytes (&opb)); memcpy (b->header2, opb.buffer, oggpack_bytes (&opb)); op_code->packet = b->header2; op_code->bytes = oggpack_bytes (&opb); op_code->b_o_s = 0; op_code->e_o_s = 0; op_code->granulepos = 0; oggpack_writeclear (&opb); return (0); err_out: oggpack_writeclear (&opb); memset (op, 0, sizeof (*op)); memset (op_comm, 0, sizeof (*op_comm)); memset (op_code, 0, sizeof (*op_code)); if (b->header) FREE (b->header); if (b->header1) FREE (b->header1); if (b->header2) FREE (b->header2); b->header = NULL; b->header1 = NULL; b->header2 = NULL; return (ret); }