Coverage Report

Created: 2025-11-24 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/pjmedia/include/pjmedia/stereo.h
Line
Count
Source
1
/* 
2
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
 */
19
#ifndef __PJMEDIA_STEREO_H__
20
#define __PJMEDIA_STEREO_H__
21
22
/**
23
 * @file stereo.h
24
 * @brief Monochannel and multichannel converter.
25
 */
26
27
#include <pjmedia/errno.h>
28
#include <pjmedia/port.h>
29
#include <pjmedia/types.h>
30
#include <pj/assert.h>
31
32
33
/**
34
 * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter
35
 * @ingroup PJMEDIA_FRAME_OP
36
 * @brief Mono - multi-channels audio conversion
37
 * @{
38
 *
39
 */
40
41
PJ_BEGIN_DECL
42
43
44
/**
45
 * Multichannel to monochannel conversion mixes samples from all channels
46
 * into the monochannel.
47
 */
48
#define PJMEDIA_STEREO_MIX  PJ_TRUE
49
50
51
52
/**
53
 * Multichannel to monochannel conversion. This function can work safely
54
 * using the same buffer (in place conversion).
55
 *
56
 * @param mono              Output buffer to store the mono frame extracted 
57
 *                          from the multichannels frame.
58
 * @param multi             Input frame containing multichannels audio.
59
 * @param channel_count     Number of channels in the input frame.
60
 * @param samples_per_frame Number of samples in the input frame.
61
 * @param mix               If the value is PJ_TRUE then the input channels 
62
 *                          will be mixed to produce output frame, otherwise
63
 *                          only frame from channel_src will be copied to the
64
 *                          output frame.
65
 * @param channel_src       When mixing is disabled, the mono output frame
66
 *                          will be copied from this channel number.
67
 *
68
 * @return                  PJ_SUCCESS on success;
69
 */
70
PJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[],
71
                                                    const pj_int16_t multi[],
72
                                                    unsigned channel_count,
73
                                                    unsigned samples_per_frame,
74
                                                    pj_bool_t mix,
75
                                                    unsigned channel_src)
76
0
{
77
0
    unsigned i;
78
0
79
0
    PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame &&
80
0
                     channel_src < channel_count,  PJ_EINVAL);
81
0
82
0
    if (mix==PJ_FALSE) {
83
0
        for (i = channel_src; i < samples_per_frame; i += channel_count) {
84
0
            *mono = multi[i];
85
0
            ++mono;
86
0
        }
87
0
    } else {
88
0
        unsigned j;
89
0
        for (i = 0; i < samples_per_frame; i += channel_count) {
90
0
            int tmp = 0;
91
0
            for(j = 0; j < channel_count; ++j)
92
0
                tmp += multi[i+j];
93
0
94
0
            if (tmp > 32767) tmp = 32767;
95
0
            else if (tmp < -32768) tmp = -32768;
96
0
            *mono = (pj_int16_t) tmp;
97
0
            ++mono;
98
0
        }
99
0
    }
100
0
101
0
    return PJ_SUCCESS;
102
0
}
103
104
105
/**
106
 * Monochannel to multichannel conversion, it will just duplicate the samples
107
 * from monochannel frame to all channels in the multichannel frame. 
108
 * This function can work safely using the same buffer (in place conversion)
109
 * as long as the buffer is big enough for the multichannel samples.
110
 *
111
 * @param multi             Output buffer to store the multichannels frame 
112
 *                          mixed from the mono frame.
113
 * @param mono              The input monochannel audio frame.
114
 * @param channel_count     Desired number of channels in the output frame.
115
 * @param samples_per_frame Number of samples in the input frame.
116
 * @param options           Options for conversion, currently must be zero.
117
 *
118
 * @return                  PJ_SUCCESS on success;
119
 */
120
PJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[],
121
                                                    const pj_int16_t mono[],
122
                                                    unsigned channel_count,
123
                                                    unsigned samples_per_frame,
124
                                                    unsigned options)
125
0
{
126
0
    const pj_int16_t *src;
127
0
128
0
    PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame, 
129
0
                     PJ_EINVAL);
130
0
    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
131
0
132
0
    PJ_UNUSED_ARG(options);
133
0
134
0
    src = mono + samples_per_frame - 1;
135
0
    samples_per_frame *= channel_count;
136
0
    while (samples_per_frame) {
137
0
        unsigned i;
138
0
        for (i=1; i<=channel_count; ++i)
139
0
            multi[samples_per_frame-i] = *src;
140
0
        samples_per_frame -= channel_count;
141
0
        --src;
142
0
    }
143
0
144
0
    return PJ_SUCCESS;
145
0
}
146
147
148
/** 
149
 * Options for channel converter port.
150
 */
151
typedef enum pjmedia_stereo_port_options
152
{
153
    /**
154
     * Specifies whether this port should not destroy downstream port when 
155
     * this port is destroyed.
156
     */
157
    PJMEDIA_STEREO_DONT_DESTROY_DN  = 4
158
} pjmedia_stereo_port_options;
159
160
161
/**
162
 * Create a mono-multi channel converter port. This creates a converter session,
163
 * which will adjust the samples of audio frame to a different channel count
164
 * when the port's get_frame() and put_frame() is called.
165
 *
166
 * When the port's get_frame() is called, this port will get a frame from 
167
 * the downstream port and convert the frame to the target channel count before
168
 * returning it to the caller.
169
 *
170
 * When the port's put_frame() is called, this port will convert the frame
171
 * to the downstream port's channel count before giving the frame to the 
172
 * downstream port.
173
 *
174
 * @param pool                  Pool to allocate the structure and buffers.
175
 * @param dn_port               The downstream port, which channel count is to
176
 *                              be converted to the target channel count.
177
 * @param channel_count         This port channel count.
178
 * @param options               Bitmask flags from #pjmedia_stereo_port_options
179
 *                              and also application may add PJMEDIA_STEREO_MIX
180
 *                              to mix channels.
181
 *                              When this flag is zero, the default behavior
182
 *                              is to use simple N-to-1 channel converter and 
183
 *                              to destroy downstream port when this port is 
184
 *                              destroyed.
185
 * @param p_port                Pointer to receive the stereo port instance.
186
 *
187
 * @return PJ_SUCCESS on success.
188
 */
189
PJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
190
                                                 pjmedia_port *dn_port,
191
                                                 unsigned channel_count,
192
                                                 unsigned options,
193
                                                 pjmedia_port **p_port );
194
195
PJ_END_DECL
196
197
/**
198
 * @}
199
 */
200
201
202
#endif  /* __PJMEDIA_STEREO_H__ */
203