Advertisement
cr88192

Experimental BCn-like Block-Audio Codec

Apr 23rd, 2013
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.26 KB | None | 0 0
  1. /*
  2. Copyright (C) 2013 by Brendan G Bohannon
  3. Email: cr88192@gmail.com
  4. Copying: http://pastebin.com/iJxtZHm6
  5.  */
  6.  
  7. /*
  8. Experimental block-based audio codec.
  9. Encodes blocks of 64 samples into 256 bits (32 bytes).
  10. At 44.1kHz this is 176kbps.
  11. It can encode stereo using a "naive joint stereo" encoding.
  12.  
  13. Basic Format:
  14.     16 bit min sample (center)
  15.     16 bit max sample (center)
  16.     8 bit left-center min (truncated)
  17.     8 bit left-center max
  18.     currently unused (16 bits)
  19.     64 Samples, 1 bits/sample (64 bits)
  20.     16x 4-bit min (64 bits)
  21.     16x 4-bit max (64 bits)
  22.  
  23. The 4-bit values interpolate between the full min/max for the block.
  24. The 1-bit samples select between the min and max value for each sample.
  25.  
  26. Note: Interpolated values are linear, thus 0=0/15, 1=1/15, 2=2/15, ..., 14=14/15, 15=15/15
  27.  
  28. Bit packing is in low-high order, and multibyte values are little-endian.
  29.  */
  30.  
  31. #include <bgbtac.h>
  32.  
  33. void BGBTAC_EncodeBlock8MonoS16(s16 *iblk, byte *oblk)
  34. {
  35.     int tcma[16], tcna[16];
  36.     int tcmb[16], tcnb[16];
  37.     int lm, ln, cm, rm, rn, cn, tl, tr, tc;
  38.     int cm2, cn2, ca2;
  39.     int p0, p1, p2, p3;
  40.     int s0, s1;
  41.     int i, j, k;
  42.  
  43.     lm= 99999; rm= 99999; cm= 99999;
  44.     ln=-99999; rn=-99999; cn=-99999;
  45.    
  46.     for(i=0; i<64; i++)
  47.     {
  48.         tl=iblk[i]; tr=tl;
  49.         k=(tl+tr)>>1;
  50.         if(k<cm) { lm=tl; rm=tr; cm=k; }
  51.         if(k>cn) { ln=tl; rn=tr; cn=k; }
  52.     }
  53.    
  54.     for(i=0; i<32; i++)
  55.         { oblk[i]=0; }
  56.    
  57.     oblk[0]=cm&0xFF;
  58.     oblk[1]=(cm>>8)&0xFF;
  59.     oblk[2]=cn&0xFF;
  60.     oblk[3]=(cn>>8)&0xFF;
  61.     oblk[4]=((lm-rm+128)>>8)&0xFF;
  62.     oblk[5]=((ln-rn+128)>>8)&0xFF;
  63.    
  64.     for(i=0; i<16; i++)
  65.     {
  66.         cm2= 99999; cn2=-99999;
  67.         for(j=0; j<4; j++)
  68.         {
  69.             tl=iblk[i*4+j]; tr=tl;
  70.             tc=(tl+tr)>>1;
  71.             if(tc<cm2) { cm2=tc; }
  72.             if(tc>cn2) { cn2=tc; }
  73.         }
  74.        
  75.         if(cn!=cm)
  76.             { s0=16777216/(cn-cm); }
  77.         else { s0=0; }
  78.  
  79.         p0=(s0*(cm2-cm)+524288)>>20;
  80.         p1=(s0*(cn2-cm)+524288)>>20;
  81.        
  82.         p0=(p0<0)?0:((p0<16)?p0:15);
  83.         p1=(p1<0)?0:((p1<16)?p1:15);
  84.        
  85.         tcma[i]=p0;
  86.         tcna[i]=p1;
  87.  
  88.         s1=(cn-cm);
  89.         cm2=((s1*p0+8)>>4)+cm;
  90.         cn2=((s1*p1+8)>>4)+cm;
  91.  
  92.         tcmb[i]=cm2;
  93.         tcnb[i]=cn2;
  94.     }
  95.  
  96.     for(i=0; i<16; i++)
  97.     {
  98.         oblk[16+(i>>1)]|=tcma[i]<<((i&1)*4);
  99.         oblk[24+(i>>1)]|=tcna[i]<<((i&1)*4);
  100.     }
  101.    
  102.     for(i=0; i<16; i++)
  103.     {
  104.         ca2=(tcmb[i]+tcnb[i])>>1;
  105.    
  106.         for(j=0; j<4; j++)
  107.         {
  108.             k=i*4+j;
  109.        
  110.             tl=iblk[k]; tr=tl;
  111. //          tl=(iblk[k]+7)>>4; tr=tl;
  112.             tc=(tl+tr)>>1;
  113.  
  114.             if(tc>=ca2)
  115.                 { oblk[8+(k>>3)]|=1<<(k&7); }
  116.             else
  117.                 { oblk[8+(k>>3)]&=~(1<<(k&7)); }
  118.         }
  119.     }  
  120. }
  121.  
  122. void BGBTAC_DecodeBlock8MonoS16(byte *iblk, s16 *oblk)
  123. {
  124.     int tcma[16], tcna[16];
  125.     int tcmb[16], tcnb[16];
  126.     int p0, p1, p2, p3;
  127.     int cm, cn, ca;
  128.     int cm2, cn2, ca2;
  129.     int i, j, k;
  130.    
  131.     cm=(s16)(iblk[0]+(iblk[1]<<8));
  132.     cn=(s16)(iblk[2]+(iblk[3]<<8));
  133.     ca=(cm+cn)>>1;
  134.  
  135.     for(i=0; i<128; i++)
  136.         { oblk[i]=ca; }
  137.        
  138.     for(i=0; i<16; i++)
  139.     {
  140.         cm2=(iblk[16+(i>>1)]>>((i&1)*4))&15;
  141.         cn2=(iblk[24+(i>>1)]>>((i&1)*4))&15;
  142. //      cm2=tcmb[i];
  143. //      cn2=tcnb[i];
  144.    
  145.         j=(cn-cm);
  146.         p0=((j*cm2+8)>>4)+cm;
  147.         p1=((j*cn2+8)>>4)+cm;
  148.  
  149.         p0=(p0<cm)?cm:((p0<cn)?p0:cn);
  150.         p1=(p1<cm)?cm:((p1<cn)?p1:cn);
  151.    
  152.         tcma[i]=p0;
  153.         tcna[i]=p1;
  154.        
  155.         p2=(p0+p1)>>1;
  156. //      if(p2<cm)p2=cm;
  157. //      if(p2>cn)p2=cn;
  158.        
  159.         for(j=0; j<4; j++)
  160.         {
  161.             k=i*4+j;
  162.        
  163. //          oblk[i*16+j]=p2;
  164.             oblk[i*4+j]=(iblk[8+(k>>3)]&(1<<(k&7)))?p1:p0;
  165.         }
  166.     }
  167. }
  168.  
  169. BTAC_API void BGBTAC_EncodeStream8MonoS16(s16 *iblk, byte *oblk, int len)
  170. {
  171.     int i, j, n;
  172.    
  173.     n=(len+63)/64;
  174.     for(i=0; i<n; i++)
  175.     {
  176.         BGBTAC_EncodeBlock8MonoS16(iblk+i*64, oblk+i*32);
  177.     }
  178. }
  179.  
  180. BTAC_API void BGBTAC_DecodeStream8MonoS16(byte *iblk, s16 *oblk, int len)
  181. {
  182.     int i, j, n;
  183.    
  184.     n=(len+63)/64;
  185.     for(i=0; i<n; i++)
  186.     {
  187.         BGBTAC_DecodeBlock8MonoS16(iblk+i*32, oblk+i*64);
  188.     }
  189. }
  190.  
  191.  
  192.  
  193. void BGBTAC_EncodeBlock8StereoS16(s16 *iblk, byte *oblk)
  194. {
  195.     s16 tcblk[64];
  196.     int tcma[16], tcna[16];
  197.     int tcmb[16], tcnb[16];
  198.     int lm, ln, cm, rm, rn, cn, tl, tr, tc;
  199.     int cm2, cn2, ca2, ba;
  200.     int p0, p1, p2, p3;
  201.     int s0, s1;
  202.     int i, j, k;
  203.  
  204.     lm= 99999; rm= 99999; cm= 99999;
  205.     ln=-99999; rn=-99999; cn=-99999;
  206.    
  207.     ba=0;
  208.     for(i=0; i<64; i++)
  209.     {
  210.         tl=iblk[i*2+0];
  211.         tr=iblk[i*2+1];
  212.         k=(tl+tr)>>1;
  213.         tcblk[i]=k;
  214.         ba+=tl-k;
  215.         if(k<cm) { lm=tl; rm=tr; cm=k; }
  216.         if(k>cn) { ln=tl; rn=tr; cn=k; }
  217.     }
  218.  
  219.     ba/=64;
  220.    
  221.     for(i=0; i<32; i++)
  222.         { oblk[i]=0; }
  223.  
  224.    
  225.     p0=(lm-cm+128)>>8;
  226.     p1=(ln-cn+128)>>8;
  227.     p2=(ba+128)>>8;
  228.     p0=(5*p0+11*p2)>>4;
  229.     p1=(5*p1+11*p2)>>4;
  230. //  p0=p2; p1=p2;
  231.  
  232.     p0=(p0<0)?0:((p0<256)?p0:255);
  233.     p1=(p1<0)?0:((p1<256)?p1:255);
  234.    
  235.     oblk[0]=cm&0xFF;
  236.     oblk[1]=(cm>>8)&0xFF;
  237.     oblk[2]=cn&0xFF;
  238.     oblk[3]=(cn>>8)&0xFF;
  239. //  oblk[4]=((lm-cm+128)>>8)&0xFF;
  240. //  oblk[5]=((ln-cn+128)>>8)&0xFF;
  241.  
  242.     oblk[4]=p0&0xFF;
  243.     oblk[5]=p1&0xFF;
  244.    
  245.     for(i=0; i<16; i++)
  246.     {
  247.         cm2= 99999; cn2=-99999;
  248.         for(j=0; j<4; j++)
  249.         {
  250.             tc=tcblk[i*4+j];
  251.             if(tc<cm2) { cm2=tc; }
  252.             if(tc>cn2) { cn2=tc; }
  253.         }
  254.        
  255.         if(cn!=cm)
  256.             { s0=16777216/(cn-cm); }
  257.         else { s0=0; }
  258.  
  259.         p0=(s0*(cm2-cm)+524288)>>20;
  260.         p1=(s0*(cn2-cm)+524288)>>20;
  261.  
  262. //      p0=(s0*(cm2-cm)+262144)>>20;
  263. //      p1=(s0*(cn2-cm)+786432)>>20;
  264.        
  265.         p0=(p0<0)?0:((p0<16)?p0:15);
  266.         p1=(p1<0)?0:((p1<16)?p1:15);
  267.        
  268.         tcma[i]=p0;
  269.         tcna[i]=p1;
  270.  
  271.         s1=(cn-cm);
  272.         cm2=((s1*p0+8)>>4)+cm;
  273.         cn2=((s1*p1+8)>>4)+cm;
  274.  
  275.         tcmb[i]=cm2;
  276.         tcnb[i]=cn2;
  277.     }
  278.  
  279.     for(i=0; i<16; i++)
  280.     {
  281.         oblk[16+(i>>1)]|=tcma[i]<<((i&1)*4);
  282.         oblk[24+(i>>1)]|=tcna[i]<<((i&1)*4);
  283.     }
  284.    
  285.     for(i=0; i<16; i++)
  286.     {
  287.         ca2=(tcmb[i]+tcnb[i])>>1;
  288.    
  289.         for(j=0; j<4; j++)
  290.         {
  291.             k=i*4+j;
  292.             tc=tcblk[k];
  293.             if(tc>=ca2)
  294.                 { oblk[8+(k>>3)]|=1<<(k&7); }
  295.             else
  296.                 { oblk[8+(k>>3)]&=~(1<<(k&7)); }
  297.         }
  298.     }  
  299. }
  300.  
  301. void BGBTAC_DecodeBlock8StereoS16(byte *iblk, s16 *oblk)
  302. {
  303. //  int tcma[16], tcna[16];
  304. //  int tcmb[16], tcnb[16];
  305.     int p0, p1, p2, p3;
  306.     int s0, s1;
  307.     int cm, cn, ca;
  308.     int lm, ln, la;
  309.     int rm, rn, ra;
  310.     int cm2, cn2, ca2;
  311.     int lm2, ln2, la2;
  312.     int rm2, rn2, ra2;
  313.     int i, j, k;
  314.    
  315.     cm=(s16)(iblk[0]+(iblk[1]<<8));
  316.     cn=(s16)(iblk[2]+(iblk[3]<<8));
  317.     ca=(cm+cn)>>1;
  318.  
  319.     i=((s16)(iblk[4]<<8));
  320.     j=((s16)(iblk[5]<<8));
  321.  
  322.     lm=cm+i; rm=cm-i;
  323.     ln=cn+j; rn=cn-j;
  324.  
  325.     lm=(lm<(-32768))?(-32768):((lm<32768)?lm:32767);
  326.     ln=(ln<(-32768))?(-32768):((ln<32768)?ln:32767);
  327.     rm=(rm<(-32768))?(-32768):((rm<32768)?rm:32767);
  328.     rn=(rn<(-32768))?(-32768):((rn<32768)?rn:32767);
  329.  
  330.     for(i=0; i<128; i++)
  331.     {
  332.         oblk[i]=ca;
  333.     }
  334.        
  335.     for(i=0; i<16; i++)
  336.     {
  337.         p0=(iblk[16+(i>>1)]>>((i&1)*4))&15;
  338.         p1=(iblk[24+(i>>1)]>>((i&1)*4))&15;
  339. //      cm2=tcmb[i];
  340. //      cn2=tcnb[i];
  341.  
  342. //      s0=(cn-cm);
  343. //      s1=(cn-cm);
  344.    
  345.         s0=(ln-lm);
  346.         s1=(rn-rm);
  347.         lm2=((s0*p0+8)>>4)+lm;
  348.         ln2=((s0*p1+8)>>4)+lm;
  349.         rm2=((s1*p0+8)>>4)+rm;
  350.         rn2=((s1*p1+8)>>4)+rm;
  351.  
  352. //      cm2=((s1*p0+8)>>4)+cm;
  353. //      cn2=((s1*p1+8)>>4)+cm;
  354.  
  355.         lm2=(lm2<lm)?lm:((lm2<ln)?lm2:ln);
  356.         ln2=(ln2<lm)?lm:((ln2<ln)?ln2:ln);
  357.         rm2=(rm2<rm)?rm:((rm2<rn)?rm2:rn);
  358.         rn2=(rn2<rm)?rm:((rn2<rn)?rn2:rn);
  359.  
  360. //      cm2=(cm2<cm)?cm:((cm2<cn)?cm2:cn);
  361. //      cn2=(cn2<cm)?cm:((cn2<cn)?cn2:cn);
  362.    
  363. //      p2=(p0+p1)>>1;
  364. //      if(p2<cm)p2=cm;
  365. //      if(p2>cn)p2=cn;
  366.        
  367.         for(j=0; j<4; j++)
  368.         {
  369.             k=i*4+j;
  370.        
  371. //          oblk[i*16+j]=p2;
  372.             p0=(iblk[8+(k>>3)]&(1<<(k&7)));
  373.             oblk[k*2+0]=p0?ln2:lm2;
  374.             oblk[k*2+1]=p0?rn2:rm2;
  375.  
  376. //          oblk[k*2+0]=p0?cn2:cm2;
  377. //          oblk[k*2+1]=p0?cn2:cm2;
  378.         }
  379.     }
  380. }
  381.  
  382. BTAC_API void BGBTAC_EncodeStream8StereoS16(s16 *iblk, byte *oblk, int len)
  383. {
  384.     int i, j, n;
  385.    
  386.     n=(len+63)/64;
  387.     for(i=0; i<n; i++)
  388.     {
  389.         BGBTAC_EncodeBlock8StereoS16(iblk+i*2*64, oblk+i*32);
  390.     }
  391. }
  392.  
  393. BTAC_API void BGBTAC_DecodeStream8StereoS16(byte *iblk, s16 *oblk, int len)
  394. {
  395.     int p0, p1, p2, p3;
  396.     int q0, q1, q2, q3;
  397.     int i, j, n;
  398.    
  399.     n=(len+63)/64;
  400.     for(i=0; i<n; i++)
  401.     {
  402.         BGBTAC_DecodeBlock8StereoS16(iblk+i*32, oblk+i*2*64);
  403.     }
  404.    
  405.     //deblocking...
  406.     for(i=1; i<(n-1); i++)
  407.         for(j=0; j<2; j++)
  408.     {
  409. #if 0
  410.         p0=oblk[i*64*2-2];
  411.         p1=oblk[i*64*2-1];
  412.         p2=oblk[i*64*2+0];
  413.         p3=oblk[i*64*2+1];
  414.  
  415.         q0=(11*p0+5*p2)>>4;
  416.         q1=(11*p1+5*p3)>>4;
  417.         q2=(11*p2+5*p0)>>4;
  418.         q3=(11*p3+5*p1)>>4;
  419.        
  420.         oblk[i*64*2-2]=q0;
  421.         oblk[i*64*2-1]=q1;
  422.         oblk[i*64*2+0]=q2;
  423.         oblk[i*64*2+1]=q3;
  424. #endif
  425.  
  426. #if 1
  427.         p0=oblk[i*64*2-4+j];
  428.         p1=oblk[i*64*2-2+j];
  429.         p2=oblk[i*64*2+0+j];
  430.         p3=oblk[i*64*2+2+j];
  431.  
  432.         q0=(128*p0+ 64*p1+ 48*p2+ 16*p3)>>8;
  433.         q1=( 48*p0+128*p1+ 48*p2+ 32*p3)>>8;
  434.         q2=( 32*p0+ 48*p1+128*p2+ 48*p3)>>8;
  435.         q3=( 16*p0+ 48*p1+ 64*p2+128*p3)>>8;
  436.        
  437.         oblk[i*64*2-4+j]=q0;
  438.         oblk[i*64*2-2+j]=q1;
  439.         oblk[i*64*2+0+j]=q2;
  440.         oblk[i*64*2+2+j]=q3;
  441. #endif
  442.     }
  443. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement