diff --git a/include/opus.h b/include/opus.h
index 623662d5cc5b2f9c3d85f21ea793a9253e70956b..847a07c1e9e7d4fd099306908783fdb5e3b3d25a 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 67e8cdb54ae31d3317540e048ed58fe7baca7ac1..cf838df753554ced12909f62e8ff24ddc822e805 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 fa62e64965300bf52a058e456e6a30d06f7af715..58c6d2b412413c29cf2dba441b9857584945af68 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();