File: wvaudioencoder.cc

package info (click to toggle)
wvstreams 4.4.1-1.1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 8,148 kB
  • ctags: 8,556
  • sloc: cpp: 64,151; ansic: 8,188; sh: 5,994; makefile: 498; perl: 277; tcl: 114
file content (110 lines) | stat: -rw-r--r-- 2,642 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * Worldvisions Weaver Software:
 *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
 *
 * Provides a WvEncoder abstraction for the SimpleAudio audio packet format.
 * suitable for encoding voice at low bitrates.
 *
 * Only monaural audio is supported for now.
 */

#include "wvaudioencoder.h"
#include "wvpcmutils.h"


/***** WvSimpleAudioEncoder *****/


WvSimpleAudioEncoder::WvSimpleAudioEncoder(unsigned int channels,
        unsigned int samplerate) :
    _channels(channels), _samplesperframe(samplerate / 1000 * 20)
{
}


bool WvSimpleAudioEncoder::_typedencode(IBuffer &inbuf, OBuffer &outbuf,
    bool flush)
{
    static WvPCMUnnormFloatToSigned16Functor f;

    for (;;)
    {
        // find how much data is available 
        size_t count = inbuf.used();
        if (count == 0) return true;
        if (count < _samplesperframe)
            return ! flush; // not enough data

        // convert this frame
        while (count > 0)
        {
            size_t avail = outbuf.optallocable();
            if (avail == 0) return false;
            if (avail > count) avail = count;
            count -= avail;

            const IType *indata = inbuf.get(avail);
            OType *outdata = outbuf.alloc(avail);
            while (avail-- > 0)
                *(outdata++) = f(*(indata++));
        }

        // return if we're not flushing
        if (! flush)
            return true;
    }
}


bool WvSimpleAudioEncoder::_typedfinish(OBuffer &outbuf)
{
    return true;
}


/***** WvSimpleAudioDecoder *****/


WvSimpleAudioDecoder::WvSimpleAudioDecoder(unsigned int channels,
        unsigned int samplerate) :
    _channels(channels), _samplesperframe(samplerate / 1000 * 20)
{
}


bool WvSimpleAudioDecoder::_typedencode(IBuffer &inbuf, OBuffer &outbuf,
    bool flush)
{
    static WvPCMSigned16ToUnnormFloatFunctor f;
    
    for (;;)
    {
        size_t avail = inbuf.used();
        if (avail == 0) return true;
        if (outbuf.free() < _samplesperframe)
            return false; // not enough room

        size_t skip = 0;
        if (avail > _samplesperframe)
        {
            // packet is too large but try to decode some audio anyhow
            skip = avail - _samplesperframe;
            avail -= skip;
        }

        const IType *indata = inbuf.get(avail);
        inbuf.skip(skip); // skip over bad data
        OType *outdata = outbuf.alloc(_samplesperframe);
        while (avail-- > 0)
            *(outdata++) = f(*(indata++));
        
        if (! flush)
            return true;
    }
}


bool WvSimpleAudioDecoder::_typedfinish(OBuffer &outbuf)
{
    return true;
}