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>
29 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
33 #include "asterisk/frame.h"
34 #include "asterisk/slinfactory.h"
35 #include "asterisk/logger.h"
36 #include "asterisk/translate.h"
38 void ast_slinfactory_init(struct ast_slinfactory
*sf
)
40 memset(sf
, 0, sizeof(*sf
));
41 sf
->offset
= sf
->hold
;
44 void ast_slinfactory_destroy(struct ast_slinfactory
*sf
)
49 ast_translator_free_path(sf
->trans
);
53 while ((f
= AST_LIST_REMOVE_HEAD(&sf
->queue
, frame_list
)))
57 int ast_slinfactory_feed(struct ast_slinfactory
*sf
, struct ast_frame
*f
)
59 struct ast_frame
*frame
, *frame_ptr
;
62 if (f
->subclass
!= AST_FORMAT_SLINEAR
) {
63 if (sf
->trans
&& f
->subclass
!= sf
->format
) {
64 ast_translator_free_path(sf
->trans
);
68 if ((sf
->trans
= ast_translator_build_path(AST_FORMAT_SLINEAR
, f
->subclass
)) == NULL
) {
69 ast_log(LOG_WARNING
, "Cannot build a path from %s to slin\n", ast_getformatname(f
->subclass
));
72 sf
->format
= f
->subclass
;
77 if (!(frame
= ast_frdup( (sf
->trans
) ? ast_translate(sf
->trans
, f
, 0) : f
)))
81 AST_LIST_TRAVERSE(&sf
->queue
, frame_ptr
, frame_list
)
84 AST_LIST_INSERT_TAIL(&sf
->queue
, frame
, frame_list
);
86 sf
->size
+= frame
->samples
;
91 int ast_slinfactory_read(struct ast_slinfactory
*sf
, short *buf
, size_t samples
)
93 struct ast_frame
*frame_ptr
;
94 unsigned int sofar
= 0, ineed
, remain
;
95 short *frame_data
, *offset
= buf
;
97 while (sofar
< samples
) {
98 ineed
= samples
- sofar
;
101 if ((sofar
+ sf
->holdlen
) <= ineed
) {
102 memcpy(offset
, sf
->hold
, sf
->holdlen
* sizeof(*offset
));
103 sofar
+= sf
->holdlen
;
104 offset
+= sf
->holdlen
;
106 sf
->offset
= sf
->hold
;
108 remain
= sf
->holdlen
- ineed
;
109 memcpy(offset
, sf
->offset
, ineed
* sizeof(*offset
));
112 sf
->holdlen
= remain
;
117 if ((frame_ptr
= AST_LIST_REMOVE_HEAD(&sf
->queue
, frame_list
))) {
118 frame_data
= frame_ptr
->data
;
120 if ((sofar
+ frame_ptr
->samples
) <= ineed
) {
121 memcpy(offset
, frame_data
, frame_ptr
->samples
* sizeof(*offset
));
122 sofar
+= frame_ptr
->samples
;
123 offset
+= frame_ptr
->samples
;
125 remain
= frame_ptr
->samples
- ineed
;
126 memcpy(offset
, frame_data
, ineed
* sizeof(*offset
));
129 memcpy(sf
->hold
, frame_data
, remain
* sizeof(*offset
));
130 sf
->holdlen
= remain
;
132 ast_frfree(frame_ptr
);
142 unsigned int ast_slinfactory_available(const struct ast_slinfactory
*sf
)