]>
code.delx.au - pulseaudio/blob - polyp/mcalign.c
4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
36 struct pa_memchunk leftover
, current
;
37 struct pa_memblock_stat
*memblock_stat
;
40 struct pa_mcalign
*pa_mcalign_new(size_t base
, struct pa_memblock_stat
*s
) {
44 m
= pa_xmalloc(sizeof(struct pa_mcalign
));
46 pa_memchunk_reset(&m
->leftover
);
47 pa_memchunk_reset(&m
->current
);
53 void pa_mcalign_free(struct pa_mcalign
*m
) {
56 if (m
->leftover
.memblock
)
57 pa_memblock_unref(m
->leftover
.memblock
);
59 if (m
->current
.memblock
)
60 pa_memblock_unref(m
->current
.memblock
);
65 void pa_mcalign_push(struct pa_mcalign
*m
, const struct pa_memchunk
*c
) {
66 assert(m
&& c
&& c
->memblock
&& c
->length
);
68 /* Append to the leftover memory block */
69 if (m
->leftover
.memblock
) {
70 assert(!m
->current
.memblock
);
73 if (m
->leftover
.memblock
== c
->memblock
&&
74 m
->leftover
.index
+ m
->leftover
.length
== c
->index
) {
77 m
->leftover
.length
+= c
->length
;
79 /* If the new chunk is larger than m->base, move it to current */
80 if (m
->leftover
.length
>= m
->base
) {
81 m
->current
= m
->leftover
;
82 pa_memchunk_reset(&m
->leftover
);
89 assert(m
->leftover
.length
< m
->base
);
90 l
= m
->base
- m
->leftover
.length
;
95 /* Can we use the current block? */
96 pa_memchunk_make_writable(&m
->leftover
, m
->memblock_stat
, m
->base
);
98 memcpy((uint8_t*) m
->leftover
.memblock
->data
+ m
->leftover
.index
+ m
->leftover
.length
, (uint8_t*) c
->memblock
->data
+ c
->index
, l
);
99 m
->leftover
.length
+= l
;
101 assert(m
->leftover
.length
<= m
->base
&& m
->leftover
.length
<= m
->leftover
.memblock
->length
);
104 /* Save the remainder of the memory block */
106 m
->current
.index
+= l
;
107 m
->current
.length
-= l
;
108 pa_memblock_ref(m
->current
.memblock
);
112 assert(!m
->leftover
.memblock
&& !m
->current
.memblock
);
114 /* Nothing to merge or copy, just store it */
116 if (c
->length
>= m
->base
)
121 pa_memblock_ref(c
->memblock
);
125 int pa_mcalign_pop(struct pa_mcalign
*m
, struct pa_memchunk
*c
) {
128 /* First test if there's a leftover memory block available */
129 if (m
->leftover
.memblock
) {
130 assert(m
->leftover
.length
> 0 && m
->leftover
.length
<= m
->base
);
132 /* The leftover memory block is not yet complete */
133 if (m
->leftover
.length
< m
->base
)
136 /* Return the leftover memory block */
138 pa_memchunk_reset(&m
->leftover
);
140 /* If the current memblock is too small move it the leftover */
141 if (m
->current
.memblock
&& m
->current
.length
< m
->base
) {
142 m
->leftover
= m
->current
;
143 pa_memchunk_reset(&m
->current
);
149 /* Now let's see if there is other data available */
150 if (m
->current
.memblock
) {
152 assert(m
->current
.length
>= m
->base
);
154 /* The length of the returned memory block */
155 l
= m
->current
.length
;
160 /* Prepare the returned block */
162 pa_memblock_ref(c
->memblock
);
165 /* Drop that from the current memory block */
166 assert(l
<= m
->current
.length
);
167 m
->current
.index
+= l
;
168 m
->current
.length
-= l
;
170 /* In case the whole block was dropped ... */
171 if (m
->current
.length
== 0)
172 pa_memblock_unref(m
->current
.memblock
);
174 /* Move the raimainder to leftover */
175 assert(m
->current
.length
< m
->base
&& !m
->leftover
.memblock
);
177 m
->leftover
= m
->current
;
180 pa_memchunk_reset(&m
->current
);
185 /* There's simply nothing */