From d0fd9d4baa84ba11b1e9057987008977b3709607 Mon Sep 17 00:00:00 2001
From: Jean-Marc Valin <jmvalin@jmvalin.ca>
Date: Tue, 4 Dec 2012 15:45:31 -0500
Subject: [PATCH] Implements opus_packet_get_nb_samples()

---
 include/opus.h        | 11 +++++++++++
 src/opus_decoder.c    | 14 ++++++++++----
 tests/test_opus_api.c |  4 +++-
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/include/opus.h b/include/opus.h
index 623662d5c..847a07c1e 100644
--- a/include/opus.h
+++ b/include/opus.h
@@ -570,6 +570,17 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsign
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
 
+/** Gets the number of samples of an Opus packet.
+  * @param [in] packet <tt>char*</tt>: Opus packet
+  * @param [in] len <tt>opus_int32</tt>: Length of packet
+  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+  *                                     This must be a multiple of 400, or
+  *                                     inaccurate results will be returned.
+  * @returns Number of samples
+  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
 /** Gets the number of samples of an Opus packet.
   * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] packet <tt>char*</tt>: Opus packet
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 67e8cdb54..cf838df75 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -1050,8 +1050,8 @@ int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
       return packet[1]&0x3F;
 }
 
-int opus_decoder_get_nb_samples(const OpusDecoder *dec,
-      const unsigned char packet[], opus_int32 len)
+int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
+      opus_int32 Fs)
 {
    int samples;
    int count = opus_packet_get_nb_frames(packet, len);
@@ -1059,10 +1059,16 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec,
    if (count<0)
       return count;
 
-   samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
+   samples = count*opus_packet_get_samples_per_frame(packet, Fs);
    /* Can't have more than 120 ms */
-   if (samples*25 > dec->Fs*3)
+   if (samples*25 > Fs*3)
       return OPUS_INVALID_PACKET;
    else
       return samples;
 }
+
+int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+      const unsigned char packet[], opus_int32 len)
+{
+   return opus_packet_get_nb_samples(packet, len, dec->Fs);
+}
diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c
index fa62e6496..58c6d2b41 100644
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -226,12 +226,14 @@ opus_int32 test_dec_api(void)
 
    VG_UNDEF(packet,sizeof(packet));
    packet[0]=0;
+   if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed();
    if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed();
    cfgs++;
    packet[0]=(63<<2)|3;
    packet[1]=63;
+   if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed();
    if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed();
-   fprintf(stdout,"    opus_decoder_get_nb_samples() ................ OK.\n");
+   fprintf(stdout,"    opus_{packet,decoder}_get_nb_samples() ................ OK.\n");
    cfgs++;
 
    if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed();
-- 
GitLab