jitter buffer: minor fix with tick()
[speexdsp.git] / libspeex / speex_header.c
1 /* Copyright (C) 2002 Jean-Marc Valin 
2    File: speex_header.c
3    Describes the Speex header
4
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8    
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11    
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15    
16    - Neither the name of the Xiph.org Foundation nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19    
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "misc.h"
39 #include <speex/speex_header.h>
40 #include <speex/speex.h>
41 #include "os_support.h"
42
43 #ifndef NULL
44 #define NULL 0
45 #endif
46
47 #define ENDIAN_SWITCH(x) {x=le_int(x);}
48
49
50 /*
51 typedef struct SpeexHeader {
52    char speex_string[8];
53    char speex_version[SPEEX_HEADER_VERSION_LENGTH];
54    int speex_version_id;
55    int header_size;
56    int rate;
57    int mode;
58    int mode_bitstream_version;
59    int nb_channels;
60    int bitrate;
61    int frame_size;
62    int vbr;
63    int frames_per_packet;
64    int extra_headers;
65    int reserved1;
66    int reserved2;
67 } SpeexHeader;
68 */
69
70 void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
71 {
72    int i;
73    const char *h="Speex   ";
74    /*
75    strncpy(header->speex_string, "Speex   ", 8);
76    strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
77    header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
78    */
79    for (i=0;i<8;i++)
80       header->speex_string[i]=h[i];
81    for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
82       header->speex_version[i]=SPEEX_VERSION[i];
83    for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
84       header->speex_version[i]=0;
85    
86    header->speex_version_id = 1;
87    header->header_size = sizeof(SpeexHeader);
88    
89    header->rate = rate;
90    header->mode = m->modeID;
91    header->mode_bitstream_version = m->bitstream_version;
92    if (m->modeID<0)
93       speex_warning("This mode is meant to be used alone");
94    header->nb_channels = nb_channels;
95    header->bitrate = -1;
96    speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
97    header->vbr = 0;
98    
99    header->frames_per_packet = 0;
100    header->extra_headers = 0;
101    header->reserved1 = 0;
102    header->reserved2 = 0;
103 }
104
105 char *speex_header_to_packet(SpeexHeader *header, int *size)
106 {
107    SpeexHeader *le_header;
108    le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
109    
110    speex_move(le_header, header, sizeof(SpeexHeader));
111    
112    /*Make sure everything is now little-endian*/
113    ENDIAN_SWITCH(le_header->speex_version_id);
114    ENDIAN_SWITCH(le_header->header_size);
115    ENDIAN_SWITCH(le_header->rate);
116    ENDIAN_SWITCH(le_header->mode);
117    ENDIAN_SWITCH(le_header->mode_bitstream_version);
118    ENDIAN_SWITCH(le_header->nb_channels);
119    ENDIAN_SWITCH(le_header->bitrate);
120    ENDIAN_SWITCH(le_header->frame_size);
121    ENDIAN_SWITCH(le_header->vbr);
122    ENDIAN_SWITCH(le_header->frames_per_packet);
123    ENDIAN_SWITCH(le_header->extra_headers);
124
125    *size = sizeof(SpeexHeader);
126    return (char *)le_header;
127 }
128
129 SpeexHeader *speex_packet_to_header(char *packet, int size)
130 {
131    int i;
132    SpeexHeader *le_header;
133    const char *h = "Speex   ";
134    for (i=0;i<8;i++)
135       if (packet[i]!=h[i])
136       {
137          speex_notify("This doesn't look like a Speex file");
138          return NULL;
139       }
140    
141    /*FIXME: Do we allow larger headers?*/
142    if (size < (int)sizeof(SpeexHeader))
143    {
144       speex_notify("Speex header too small");
145       return NULL;
146    }
147    
148    le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
149    
150    speex_move(le_header, packet, sizeof(SpeexHeader));
151    
152    /*Make sure everything is converted correctly from little-endian*/
153    ENDIAN_SWITCH(le_header->speex_version_id);
154    ENDIAN_SWITCH(le_header->header_size);
155    ENDIAN_SWITCH(le_header->rate);
156    ENDIAN_SWITCH(le_header->mode);
157    ENDIAN_SWITCH(le_header->mode_bitstream_version);
158    ENDIAN_SWITCH(le_header->nb_channels);
159    ENDIAN_SWITCH(le_header->bitrate);
160    ENDIAN_SWITCH(le_header->frame_size);
161    ENDIAN_SWITCH(le_header->vbr);
162    ENDIAN_SWITCH(le_header->frames_per_packet);
163    ENDIAN_SWITCH(le_header->extra_headers);
164
165    return le_header;
166
167 }