Fixing warnings (patch by Alfred E. Heggestad)
[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
42 #ifndef NULL
43 #define NULL 0
44 #endif
45
46 #define ENDIAN_SWITCH(x) {x=le_int(x);}
47
48
49 /*
50 typedef struct SpeexHeader {
51    char speex_string[8];
52    char speex_version[SPEEX_HEADER_VERSION_LENGTH];
53    int speex_version_id;
54    int header_size;
55    int rate;
56    int mode;
57    int mode_bitstream_version;
58    int nb_channels;
59    int bitrate;
60    int frame_size;
61    int vbr;
62    int frames_per_packet;
63    int extra_headers;
64    int reserved1;
65    int reserved2;
66 } SpeexHeader;
67 */
68
69 void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
70 {
71    int i;
72    const char *h="Speex   ";
73    /*
74    strncpy(header->speex_string, "Speex   ", 8);
75    strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
76    header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
77    */
78    for (i=0;i<8;i++)
79       header->speex_string[i]=h[i];
80    for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
81       header->speex_version[i]=SPEEX_VERSION[i];
82    for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
83       header->speex_version[i]=0;
84    
85    header->speex_version_id = 1;
86    header->header_size = sizeof(SpeexHeader);
87    
88    header->rate = rate;
89    header->mode = m->modeID;
90    header->mode_bitstream_version = m->bitstream_version;
91    if (m->modeID<0)
92       speex_warning("This mode is meant to be used alone");
93    header->nb_channels = nb_channels;
94    header->bitrate = -1;
95    speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
96    header->vbr = 0;
97    
98    header->frames_per_packet = 0;
99    header->extra_headers = 0;
100    header->reserved1 = 0;
101    header->reserved2 = 0;
102 }
103
104 char *speex_header_to_packet(SpeexHeader *header, int *size)
105 {
106    SpeexHeader *le_header;
107    le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
108    
109    speex_move(le_header, header, sizeof(SpeexHeader));
110    
111    /*Make sure everything is now little-endian*/
112    ENDIAN_SWITCH(le_header->speex_version_id);
113    ENDIAN_SWITCH(le_header->header_size);
114    ENDIAN_SWITCH(le_header->rate);
115    ENDIAN_SWITCH(le_header->mode);
116    ENDIAN_SWITCH(le_header->mode_bitstream_version);
117    ENDIAN_SWITCH(le_header->nb_channels);
118    ENDIAN_SWITCH(le_header->bitrate);
119    ENDIAN_SWITCH(le_header->frame_size);
120    ENDIAN_SWITCH(le_header->vbr);
121    ENDIAN_SWITCH(le_header->frames_per_packet);
122    ENDIAN_SWITCH(le_header->extra_headers);
123
124    *size = sizeof(SpeexHeader);
125    return (char *)le_header;
126 }
127
128 SpeexHeader *speex_packet_to_header(char *packet, int size)
129 {
130    int i;
131    SpeexHeader *le_header;
132    const char *h = "Speex   ";
133    for (i=0;i<8;i++)
134       if (packet[i]!=h[i])
135       {
136          speex_warning ("This doesn't look like a Speex file");
137          return NULL;
138       }
139    
140    /*FIXME: Do we allow larger headers?*/
141    if (size < (int)sizeof(SpeexHeader))
142    {
143       speex_warning("Speex header too small");
144       return NULL;
145    }
146    
147    le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
148    
149    speex_move(le_header, packet, sizeof(SpeexHeader));
150    
151    /*Make sure everything is converted correctly from little-endian*/
152    ENDIAN_SWITCH(le_header->speex_version_id);
153    ENDIAN_SWITCH(le_header->header_size);
154    ENDIAN_SWITCH(le_header->rate);
155    ENDIAN_SWITCH(le_header->mode);
156    ENDIAN_SWITCH(le_header->mode_bitstream_version);
157    ENDIAN_SWITCH(le_header->nb_channels);
158    ENDIAN_SWITCH(le_header->bitrate);
159    ENDIAN_SWITCH(le_header->frame_size);
160    ENDIAN_SWITCH(le_header->vbr);
161    ENDIAN_SWITCH(le_header->frames_per_packet);
162    ENDIAN_SWITCH(le_header->extra_headers);
163
164    return le_header;
165
166 }