Implement signalling byte at the start of a packet
authorJean-Marc Valin <jean-marc.valin@octasic.com>
Tue, 7 Sep 2010 21:37:56 +0000 (17:37 -0400)
committerJean-Marc Valin <jean-marc.valin@octasic.com>
Tue, 7 Sep 2010 21:37:56 +0000 (17:37 -0400)
src/hybrid_decoder.c
src/hybrid_encoder.c
src/test_hybrid.c

index d76f43a..e095701 100644 (file)
@@ -87,9 +87,38 @@ int hybrid_decode(HybridDecoder *st, const unsigned char *data,
     SKP_SILK_SDK_DecControlStruct DecControl;
     SKP_int16 silk_frame_size;
     short pcm_celt[960];
+    int audiosize;
 
     if (data != NULL)
     {
+        /* Decoding mode/bandwidth/framesize from first byte */
+        if (data[0]&0x80)
+        {
+            st->mode = MODE_CELT_ONLY;
+            st->bandwidth = BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
+            if (st->bandwidth == BANDWIDTH_MEDIUMBAND)
+                st->bandwidth = BANDWIDTH_NARROWBAND;
+            audiosize = ((data[0]>>3)&0x3);
+            audiosize = (st->Fs<<audiosize)/400;
+        } else if ((data[0]&0x60) == 0x60)
+        {
+            st->mode = MODE_HYBRID;
+            st->bandwidth = (data[0]&0x10) ? BANDWIDTH_FULLBAND : BANDWIDTH_SUPERWIDEBAND;
+            audiosize = (data[0]&0x08) ? st->Fs/50 : st->Fs/100;
+        } else {
+
+            st->mode = MODE_SILK_ONLY;
+            st->bandwidth = BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
+            audiosize = ((data[0]>>3)&0x3);
+            if (audiosize == 3)
+                audiosize = st->Fs*60/1000;
+            else
+                audiosize = (st->Fs<<audiosize)/100;
+        }
+        /*printf ("%d %d %d\n", st->mode, st->bandwidth, audiosize);*/
+
+        len -= 1;
+        data += 1;
         ec_byte_readinit(&buf,(unsigned char*)data,len);
         ec_dec_init(&dec,&buf);
     }
index 5289d8f..d931f07 100644 (file)
@@ -96,7 +96,10 @@ int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size,
        ec_enc enc;
        ec_byte_buffer buf;
        SKP_SILK_SDK_EncControlStruct encControl;
+       int framerate, period;
 
+       bytes_per_packet -= 1;
+       data += 1;
        ec_byte_writeinit_buffer(&buf, data, bytes_per_packet);
        ec_enc_init(&enc,&buf);
 
@@ -168,14 +171,43 @@ int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size,
             ec_byte_shrink(&buf, bytes_per_packet);
         }
            /* Encode high band with CELT */
-           ret = celt_encode_with_ec(st->celt_enc, pcm_buf, NULL, frame_size, data, bytes_per_packet, &enc);
+           ret = celt_encode_with_ec(st->celt_enc, pcm_buf, NULL, frame_size, NULL, bytes_per_packet, &enc);
            for (i=0;i<ENCODER_DELAY_COMPENSATION;i++)
                st->delay_buffer[i] = pcm[frame_size-ENCODER_DELAY_COMPENSATION+i];
        } else {
            ec_enc_done(&enc);
        }
 
-       return ret;
+       /* Signalling the mode in the first byte */
+       data--;
+       framerate = st->Fs/frame_size;
+       period = 0;
+       while (framerate < 400)
+       {
+           framerate <<= 1;
+           period++;
+       }
+    if (st->mode == MODE_SILK_ONLY)
+    {
+        data[0] = (st->bandwidth-BANDWIDTH_NARROWBAND)<<5;
+        data[0] |= (period-2)<<3;
+    } else if (st->mode == MODE_CELT_ONLY)
+    {
+        int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
+        if (tmp < 0)
+            tmp = 0;
+        data[0] = 0x80;
+        data[0] |= tmp << 5;
+        data[0] |= period<<3;
+    } else /* Hybrid */
+    {
+        data[0] = 0x60;
+        data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
+        data[0] |= (period-2)<<3;
+    }
+    /*printf ("%x\n", (int)data[0]);*/
+
+    return ret+1;
 }
 
 void hybrid_encoder_ctl(HybridEncoder *st, int request, ...)
index 5d4a5fc..9a547a8 100644 (file)
@@ -112,9 +112,6 @@ int main(int argc, char *argv[])
    hybrid_encoder_ctl(enc, HYBRID_SET_BANDWIDTH(BANDWIDTH_FULLBAND));
    hybrid_encoder_ctl(enc, HYBRID_SET_MODE(mode));
 
-   hybrid_decoder_ctl(dec, HYBRID_SET_BANDWIDTH(BANDWIDTH_FULLBAND));
-   hybrid_decoder_ctl(dec, HYBRID_SET_MODE(mode));
-
    if (vbr)
        hybrid_encoder_ctl(enc, HYBRID_SET_VBR_RATE(vbr));