2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2005, Anthony Minessale II.
6 * Anthony Minessale <anthmct@yahoo.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief A machine to gather up arbitrary frames and convert them
22 * to raw slinear on demand.
24 * \author Anthony Minessale <anthmct@yahoo.com>
31 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
33 #include "asterisk/slinfactory.h"
34 #include "asterisk/logger.h"
35 #include "asterisk/translate.h"
38 void ast_slinfactory_init(struct ast_slinfactory
*sf
)
40 memset(sf
, 0, sizeof(struct ast_slinfactory
));
41 sf
->offset
= sf
->hold
;
45 void ast_slinfactory_destroy(struct ast_slinfactory
*sf
)
50 ast_translator_free_path(sf
->trans
);
54 while((f
= sf
->queue
)) {
60 int ast_slinfactory_feed(struct ast_slinfactory
*sf
, struct ast_frame
*f
)
62 struct ast_frame
*frame
, *frame_ptr
;
68 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
69 if (sf
->trans
&& f
->subclass
!= sf
->format
) {
70 ast_translator_free_path(sf
->trans
);
74 if ((sf
->trans
= ast_translator_build_path(AST_FORMAT_SLINEAR
, f
->subclass
)) == NULL
) {
75 ast_log(LOG_WARNING
, "Cannot build a path from %s to slin\n", ast_getformatname(f
->subclass
));
78 sf
->format
= f
->subclass
;
84 frame
= ast_translate(sf
->trans
, f
, 0);
91 for (frame_ptr
= sf
->queue
; frame_ptr
&& frame_ptr
->next
; frame_ptr
=frame_ptr
->next
) {
95 frame_ptr
->next
= frame
;
100 sf
->size
+= frame
->datalen
;
108 int ast_slinfactory_read(struct ast_slinfactory
*sf
, short *buf
, size_t bytes
)
110 struct ast_frame
*frame_ptr
;
111 int sofar
= 0, ineed
, remain
;
112 short *frame_data
, *offset
= buf
;
114 while (sofar
< bytes
) {
115 ineed
= bytes
- sofar
;
118 if ((sofar
+ sf
->holdlen
) <= ineed
) {
119 memcpy(offset
, sf
->hold
, sf
->holdlen
);
120 sofar
+= sf
->holdlen
;
121 offset
+= (sf
->holdlen
/ sizeof(short));
123 sf
->offset
= sf
->hold
;
125 remain
= sf
->holdlen
- ineed
;
126 memcpy(offset
, sf
->offset
, ineed
);
128 sf
->offset
+= (ineed
/ sizeof(short));
129 sf
->holdlen
= remain
;
134 if ((frame_ptr
= sf
->queue
)) {
135 sf
->queue
= frame_ptr
->next
;
136 frame_data
= frame_ptr
->data
;
138 if ((sofar
+ frame_ptr
->datalen
) <= ineed
) {
139 memcpy(offset
, frame_data
, frame_ptr
->datalen
);
140 sofar
+= frame_ptr
->datalen
;
141 offset
+= (frame_ptr
->datalen
/ sizeof(short));
143 remain
= frame_ptr
->datalen
- ineed
;
144 memcpy(offset
, frame_data
, ineed
);
146 frame_data
+= (ineed
/ sizeof(short));
147 memcpy(sf
->hold
, frame_data
, remain
);
148 sf
->holdlen
= remain
;
150 ast_frfree(frame_ptr
);