comment added.
[swftools.git] / lib / modules / swfsound.c
1 /* swfaction.c
2
3    SWF Sound handling routines
4    
5    Extension module for the rfxswf library.
6    Part of the swftools package.
7
8    Copyright (c) 2001, 2002 Matthias Kramm <kramm@quiss.org>
9  
10    This file is distributed under the GPL, see file COPYING for details 
11
12 */
13
14 #ifndef RFXSWF_DISABLESOUND
15
16 #include "../rfxswf.h"
17
18 #ifdef BLADEENC
19 fjokjklj
20 CodecInitOut * init = 0;
21 void swf_SetSoundStreamHead(TAG*tag, U16 avgnumsamples)
22 {
23     U8 playbackrate = 3; // 0 = 5.5 Khz, 1 = 11 Khz, 2 = 22 Khz, 3 = 44 Khz
24     U8 playbacksize = 1; // 0 = 8 bit, 1 = 16 bit
25     U8 playbacktype = 0; // 0 = mono, 1 = stereo
26     U8 compression = 2; // 0 = raw, 1 = ADPCM, 2 = mp3, 3 = raw le, 6 = nellymoser
27     U8 rate = 3; // 0 = 5.5 Khz, 1 = 11 Khz, 2 = 22 Khz, 3 = 44 Khz
28     U8 size = 1; // 0 = 8 bit, 1 = 16 bit
29     U8 type = 0; // 0 = mono, 1 = stereo
30
31     CodecInitIn params;
32     memset(&params, 0, sizeof(params));
33     params.frequency = 44100;  //48000, 44100 or 32000
34     params.mode = 3;      //0 = Stereo, 2 = Dual Channel, 3 = Mono
35     params.emphasis = 0;  //0 = None, 1 = 50/15 microsec, 3 = CCITT J.17
36     params.bitrate = 128;         //default is 128 (64 for mono)
37     init = codecInit(&params);
38
39     swf_SetU8(tag,(playbackrate<<2)|(playbacksize<<1)|playbacktype);
40     swf_SetU8(tag,(compression<<4)|(rate<<2)|(size<<1)|type);
41     swf_SetU16(tag,avgnumsamples);
42
43     printf("numSamples:%d\n",init->nSamples);
44     printf("bufferSize:%d\n",init->bufferSize);
45 }
46
47 void swf_SetSoundStreamBlock(TAG*tag, S16*samples, int numsamples, char first)
48 {
49     char*buf;
50     int len = 0;
51
52     buf = malloc(init->bufferSize);
53     if(!buf)
54         return;
55     
56     len = codecEncodeChunk (numsamples, samples, buf);
57     len += codecFlush (&buf[len]);
58     len += codecExit (&buf[len]);
59
60     if(first) {
61         swf_SetU16(tag, numsamples); // number of samples
62         swf_SetU16(tag, 0); // seek
63     }
64     swf_SetBlock(tag, buf, len);
65     free(buf);
66 }
67 #endif
68
69
70 #ifdef LAME
71
72 #include "../lame/lame.h"
73     
74 static lame_global_flags*lame_flags;
75
76 static void initlame(unsigned char*buf, int bufsize)
77 {
78     lame_flags = lame_init();
79
80     lame_set_in_samplerate(lame_flags, 44100);
81     lame_set_num_channels(lame_flags, 1);
82     lame_set_scale(lame_flags, 0);
83
84     // MPEG1    32, 44.1,   48khz
85     // MPEG2    16, 22.05,  24
86     // MPEG2.5   8, 11.025, 12
87     // (not used by decoding routines)
88     lame_set_out_samplerate(lame_flags, 11025);
89
90     lame_set_quality(lame_flags, 0);
91     lame_set_mode(lame_flags, MONO/*3*/);
92     //lame_set_compression_ratio(lame_flags, 11.025);
93     lame_set_bWriteVbrTag(lame_flags, 0);
94
95     lame_init_params(lame_flags);
96     lame_init_bitstream(lame_flags);
97
98     /* The first two flush calls to lame always fail, for
99        some reason. Do them here where they cause no damage. */
100     lame_encode_flush_nogap(lame_flags, buf, bufsize);
101     //printf("init:flush_nogap():%d\n", len);
102     lame_encode_flush(lame_flags, buf, bufsize);
103     //printf("init:flush():%d\n", len);
104 }
105
106 void swf_SetSoundStreamHead(TAG*tag, int avgnumsamples)
107 {
108     unsigned char buf[4096];
109     int bufsize = 1152*2;
110     int len;
111     short int samples[1152*2];
112
113     U8 playbackrate = 1; // 0 = 5.5 Khz, 1 = 11 Khz, 2 = 22 Khz, 3 = 44 Khz
114     U8 playbacksize = 1; // 0 = 8 bit, 1 = 16 bit
115     U8 playbacktype = 0; // 0 = mono, 1 = stereo
116     U8 compression = 2; // 0 = raw, 1 = ADPCM, 2 = mp3, 3 = raw le, 6 = nellymoser
117     U8 rate = 1; // 0 = 5.5 Khz, 1 = 11 Khz, 2 = 22 Khz, 3 = 44 Khz
118     U8 size = 1; // 0 = 8 bit, 1 = 16 bit
119     U8 type = 0; // 0 = mono, 1 = stereo
120     
121     memset(samples,0,sizeof(samples));
122
123     initlame(buf, bufsize);
124
125     swf_SetU8(tag,(playbackrate<<2)|(playbacksize<<1)|playbacktype);
126     swf_SetU8(tag,(compression<<4)|(rate<<2)|(size<<1)|type);
127     swf_SetU16(tag,avgnumsamples);
128 }
129
130 void swf_SetSoundStreamBlock(TAG*tag, S16*samples, int seek, char first)
131 {
132     char*buf;
133     int oldlen=0,len = 0;
134     int bufsize = 16384;
135     int numsamples = 1152*2;
136
137     buf = malloc(bufsize);
138     if(!buf)
139         return;
140
141     if(first) {
142         int fs = lame_get_framesize(lame_flags);
143         //printf("framesize:%d\n", fs);
144         swf_SetU16(tag, fs); // samples per mp3 frame
145         swf_SetU16(tag, seek); // seek
146     }
147
148     len += lame_encode_buffer(lame_flags, samples, samples, numsamples, &buf[len], bufsize-len);
149     //printf("block: %d (+%d)\n", len, len-oldlen);
150     oldlen = len;
151
152     len += lame_encode_flush_nogap(lame_flags, &buf[len], bufsize-len);
153     //printf("flush: %d (+%d)\n", len, len-oldlen);
154     oldlen = len;
155     
156     swf_SetBlock(tag, buf, len);
157
158    /* len += lame_encode_flush(lame_flags, &buf[len], bufsize-len);
159     printf("flush! %d (+%d)\n", len, len-oldlen);*/
160
161     free(buf);
162 }
163
164 void swf_SetSoundStreamEnd(TAG*tag)
165 {
166     lame_close (lame_flags);
167 }
168
169 void swf_SetSoundDefine(TAG*tag, S16*samples, int num)
170 {
171     char*buf;
172     int oldlen=0,len = 0;
173     int bufsize = 16384;
174     int blocksize = 1152*2;
175     int t;
176     int blocks;
177
178     U8 compression = 2; // 0 = raw, 1 = ADPCM, 2 = mp3, 3 = raw le, 6 = nellymoser
179     U8 rate = 1; // 0 = 5.5 Khz, 1 = 11 Khz, 2 = 22 Khz, 3 = 44 Khz
180     U8 size = 1; // 0 = 8 bit, 1 = 16 bit
181     U8 type = 0; // 0 = mono, 1 = stereo
182
183     blocks = num / (blocksize);
184
185     swf_SetU8(tag,(compression<<4)|(rate<<2)|(size<<1)|type);
186     swf_SetU32(tag,blocks*blocksize);
187
188     buf = malloc(bufsize);
189     if(!buf)
190         return;
191
192     initlame(buf, bufsize);
193
194     swf_SetU16(tag, 0); //delayseek
195     for(t=0;t<blocks;t++) {
196         int s;
197         U16*pos;
198         pos= &samples[t*blocksize];
199         len += lame_encode_buffer(lame_flags, pos, pos, blocksize, &buf[len], bufsize-len);
200         len += lame_encode_flush_nogap(lame_flags, &buf[len], bufsize-len);
201         swf_SetBlock(tag, buf, len);
202         len = 0;
203     }
204
205     free(buf);
206 }
207
208 #define SOUNDINFO_STOP 32
209 #define SOUNDINFO_NOMULTIPLE 16
210 #define SOUNDINFO_HASENVELOPE 8
211 #define SOUNDINFO_HASLOOPS 4
212 #define SOUNDINFO_HASOUTPOINT 2
213 #define SOUNDINFO_HASINPOINT 1
214
215 void swf_SetSoundInfo(TAG*tag, SOUNDINFO*info)
216 {
217     U8 flags = (info->stop?SOUNDINFO_STOP:0)
218               |(info->multiple?SOUNDINFO_NOMULTIPLE:0)
219               |(info->envelopes?SOUNDINFO_HASENVELOPE:0)
220               |(info->loops?SOUNDINFO_HASLOOPS:0)
221               |(info->outpoint?SOUNDINFO_HASOUTPOINT:0)
222               |(info->inpoint?SOUNDINFO_HASINPOINT:0);
223     swf_SetU8(tag, flags);
224     if(flags&SOUNDINFO_HASINPOINT)
225         swf_SetU32(tag, info->inpoint);
226     if(flags&SOUNDINFO_HASOUTPOINT)
227         swf_SetU32(tag, info->outpoint);
228     if(flags&SOUNDINFO_HASLOOPS)
229         swf_SetU16(tag, info->loops);
230     if(flags&SOUNDINFO_HASENVELOPE) {
231         int t;
232         swf_SetU8(tag, info->envelopes);
233         for(t=0;t<info->envelopes;t++) {
234             swf_SetU32(tag, info->pos[t]);
235             swf_SetU16(tag, info->left[t]);
236             swf_SetU16(tag, info->right[t]);
237         }
238     }
239 }
240
241 #endif
242
243 #endif // RFXSWF_DISABLESOUND