Line data Source code
1 : /***********************************************************************
2 : Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3 : Redistribution and use in source and binary forms, with or without
4 : modification, are permitted provided that the following conditions
5 : are met:
6 : - Redistributions of source code must retain the above copyright notice,
7 : this list of conditions and the following disclaimer.
8 : - Redistributions in binary form must reproduce the above copyright
9 : notice, this list of conditions and the following disclaimer in the
10 : documentation and/or other materials provided with the distribution.
11 : - Neither the name of Internet Society, IETF or IETF Trust, nor the
12 : names of specific contributors, may be used to endorse or promote
13 : products derived from this software without specific prior written
14 : permission.
15 : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 : ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 : LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 : CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 : SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 : INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 : CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 : ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 : POSSIBILITY OF SUCH DAMAGE.
26 : ***********************************************************************/
27 :
28 : #ifdef HAVE_CONFIG_H
29 : #include "config.h"
30 : #endif
31 :
32 : #include "main.h"
33 : #include "tuning_parameters.h"
34 :
35 : /* Control internal sampling rate */
36 0 : opus_int silk_control_audio_bandwidth(
37 : silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
38 : silk_EncControlStruct *encControl /* I Control structure */
39 : )
40 : {
41 : opus_int fs_kHz;
42 : opus_int32 fs_Hz;
43 :
44 0 : fs_kHz = psEncC->fs_kHz;
45 0 : fs_Hz = silk_SMULBB( fs_kHz, 1000 );
46 0 : if( fs_Hz == 0 ) {
47 : /* Encoder has just been initialized */
48 0 : fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz );
49 0 : fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
50 0 : } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) {
51 : /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
52 0 : fs_Hz = psEncC->API_fs_Hz;
53 0 : fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz );
54 0 : fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz );
55 0 : fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
56 : } else {
57 : /* State machine for the internal sampling rate switching */
58 0 : if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
59 : /* Stop transition phase */
60 0 : psEncC->sLP.mode = 0;
61 : }
62 0 : if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
63 : /* Check if we should switch down */
64 0 : if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
65 : {
66 : /* Switch down */
67 0 : if( psEncC->sLP.mode == 0 ) {
68 : /* New transition */
69 0 : psEncC->sLP.transition_frame_no = TRANSITION_FRAMES;
70 :
71 : /* Reset transition filter state */
72 0 : silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
73 : }
74 0 : if( encControl->opusCanSwitch ) {
75 : /* Stop transition phase */
76 0 : psEncC->sLP.mode = 0;
77 :
78 : /* Switch to a lower sample frequency */
79 0 : fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8;
80 : } else {
81 0 : if( psEncC->sLP.transition_frame_no <= 0 ) {
82 0 : encControl->switchReady = 1;
83 : /* Make room for redundancy */
84 0 : encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
85 : } else {
86 : /* Direction: down (at double speed) */
87 0 : psEncC->sLP.mode = -2;
88 : }
89 : }
90 : }
91 : else
92 : /* Check if we should switch up */
93 0 : if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
94 : {
95 : /* Switch up */
96 0 : if( encControl->opusCanSwitch ) {
97 : /* Switch to a higher sample frequency */
98 0 : fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16;
99 :
100 : /* New transition */
101 0 : psEncC->sLP.transition_frame_no = 0;
102 :
103 : /* Reset transition filter state */
104 0 : silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
105 :
106 : /* Direction: up */
107 0 : psEncC->sLP.mode = 1;
108 : } else {
109 0 : if( psEncC->sLP.mode == 0 ) {
110 0 : encControl->switchReady = 1;
111 : /* Make room for redundancy */
112 0 : encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
113 : } else {
114 : /* Direction: up */
115 0 : psEncC->sLP.mode = 1;
116 : }
117 : }
118 : } else {
119 0 : if (psEncC->sLP.mode<0)
120 0 : psEncC->sLP.mode = 1;
121 : }
122 : }
123 : }
124 :
125 0 : return fs_kHz;
126 : }
|