X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=src%2Fwav2swf.c;h=c5744b74831e945a4ce44c0b8b85f2f1949d4304;hp=0b233c717f07bc217ae4ec53aabb871ae5a3111d;hb=0f50b9ef526a82c2e86e0a90fc707c0aa43d3e36;hpb=23cda857a4248617d746a37dca4652604ef11a1e diff --git a/src/wav2swf.c b/src/wav2swf.c index 0b233c7..c5744b7 100644 --- a/src/wav2swf.c +++ b/src/wav2swf.c @@ -1,11 +1,23 @@ -/* swfextract.c - Allows to extract parts of the swf into a new file. +/* wav2swf.c + Converts WAV/WAVE files to SWF. Part of the swftools package. Copyright (c) 2001 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This file is distributed under the GPL, see file COPYING for details */ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -17,19 +29,35 @@ char * filename = 0; char * outputname = "output.swf"; int verbose = 2; +int stopframe0 = 0; -struct options_t options[] = -{ - {"o","output"}, - {"v","verbose"}, - {"d","definesound"}, - {"l","loop"}, - {"V","version"}, - {0,0} +#define DEFINESOUND_MP3 1 //define sound uses mp3?- undefine for raw sound. + +static struct options_t options[] = { +{"h", "help"}, +{"V", "version"}, +{"o", "output"}, +{"r", "framerate"}, +{"s", "samplerate"}, +{"b", "bitrate"}, +{"d", "definesound"}, +{"l", "loop"}, +{"C", "cgi"}, +{"S", "stop"}, +{"b", "bitrate"}, +{"v", "verbose"}, +{0,0} }; static int loop = 0; static int definesound = 0; +static int framerate = 0; +static int samplerate = 11025; +static int bitrate = 32; +static int do_cgi = 0; + +static int mp3_bitrates[] = +{ 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}; int args_callback_option(char*name,char*val) { @@ -47,12 +75,68 @@ int args_callback_option(char*name,char*val) } else if(!strcmp(name, "l")) { loop = atoi(val); + definesound = 1; return 1; } else if(!strcmp(name, "v")) { verbose ++; return 0; } + else if(!strcmp(name, "S")) { + stopframe0 = 1; + return 0; + } + else if(!strcmp(name, "C")) { + do_cgi = 1; + return 0; + } + else if(!strcmp(name, "r")) { + float f; + sscanf(val, "%f", &f); + framerate = f*256; + return 1; + } + else if(!strcmp(name, "s")) { + samplerate = atoi(val); + if(samplerate > 5000 && samplerate < 6000) + samplerate = 5512; + else if(samplerate > 11000 && samplerate < 12000) + samplerate = 11025; + else if(samplerate > 22000 && samplerate < 23000) + samplerate = 22050; + else if(samplerate > 44000 && samplerate < 45000) + samplerate = 44100; + else { + fprintf(stderr, "Invalid samplerate: %d\n", samplerate); + fprintf(stderr, "Allowed values: 11025, 22050, 44100\n", samplerate); + exit(1); + } + return 1; + } + else if(!strcmp(name, "b")) { + int t; + int b = atoi(val); + if(b<=0) { + fprintf(stderr, "Not a valid bitrate: %s\n", val); + exit(1); + } + if(b>160) { + fprintf(stderr, "Bitrate must be <144. (%s)\n", val); + exit(1); + } + for(t=0;mp3_bitrates[t];t++) { + if(b== mp3_bitrates[t]) { + bitrate = b; + return 1; + } + } + fprintf(stderr, "Invalid bitrate. Allowed bitrates are:\n"); + for(t=0;mp3_bitrates[t];t++) { + printf("%d ", mp3_bitrates[t]); + } + printf("\n"); + exit(1); + } else { printf("Unknown option: -%s\n", name); exit(1); @@ -63,14 +147,24 @@ int args_callback_longoption(char*name,char*val) { return args_long2shortoption(options, name, val); } -void args_callback_usage(char*name) +void args_callback_usage(char *name) { + printf("\n"); printf("Usage: %s [-o filename] file.wav\n", name); - printf("\t-v , --verbose\t\t\t Be more verbose\n"); - printf("\t-d , --definesound\t\t\t Generate a DefineSound tag instead of streaming sound\n"); - printf("\t-l , --loop n\t\t\t Loop sound n times (implies -d)\n"); - printf("\t-o , --output filename\t\t set output filename (default: output.swf)\n"); - printf("\t-V , --version\t\t\t Print program version and exit\n"); + printf("\n"); + printf("-h , --help Print short help message and exit\n"); + printf("-V , --version Print version info and exit\n"); + printf("-o , --output Explicitly specify output file. (Otherwise, output will go to output.swf)\n"); + printf("-r , --framerate Set file framerate to frames per second.\n"); + printf("-s , --samplerate Set samplerate to frames per second (default: 11025).\n"); + printf("-b , --bitrate bps Set mp3 bitrate to .\n"); + printf("-d , --definesound Generate a DefineSound tag instead of streaming sound.\n"); + printf("-l , --loop n (Only used with -d)\n"); + printf("-C , --cgi For use as CGI- prepend http header, write to stdout.\n"); + printf("-S , --stop Stop the movie at frame 0\n"); + printf("-b , --bitrate Set mp3 bitrate to (default: 32)\n"); + printf("-v , --verbose Be more verbose\n"); + printf("\n"); } int args_callback_command(char*name,char*val) { @@ -82,6 +176,10 @@ int args_callback_command(char*name,char*val) return 0; } +extern int swf_mp3_bitrate; +extern int swf_mp3_out_samplerate; +extern int swf_mp3_in_samplerate; + int main (int argc,char ** argv) { SWF swf; @@ -94,28 +192,65 @@ int main (int argc,char ** argv) int count; int t; struct WAV wav,wav2; - int blocksize = 1152; + int blocksize; + float blockspersecond; + float framespersecond; + float samplesperframe; + float framesperblock; + float samplesperblock; U16* samples; int numsamples; processargs(argc, argv); + + blocksize = (samplerate > 22050) ? 1152 : 576; + + blockspersecond = (float)samplerate/blocksize; + + framespersecond = blockspersecond; + if(framerate) + framespersecond = framerate/256.0; + + framesperblock = framespersecond / blockspersecond; + samplesperframe = (blocksize * blockspersecond) / framespersecond; + samplesperblock = samplesperframe * framesperblock; + initLog(0,-1,0,0,-1,verbose); + if(!filename) { + msg(" You must supply a filename"); + exit(1); + } + if(!readWAV(filename, &wav)) { - logf(" Error reading %s", filename); + msg(" Error reading %s", filename); exit(1); } - convertWAV2mono(&wav,&wav2, 44100); + convertWAV2mono(&wav,&wav2, samplerate); //printWAVInfo(&wav); //printWAVInfo(&wav2); samples = (U16*)wav2.data; numsamples = wav2.size/2; + if(numsamples%blocksize != 0) + { + // apply padding, so that block is a multiple of blocksize + int numblocks = (numsamples+blocksize-1)/blocksize; + int numsamples2; + U16* samples2; + numsamples2 = numblocks * blocksize; + samples2 = malloc(sizeof(U16)*numsamples2); + memcpy(samples2, samples, numsamples*sizeof(U16)); + memset(&samples2[numsamples], 0, sizeof(U16)*(numsamples2 - numsamples)); + numsamples = numsamples2; + samples = samples2; + } + memset(&swf,0x00,sizeof(SWF)); swf.fileVersion = 5; - swf.frameRate = 11025*256/(blocksize); + swf.frameRate = (int)(framespersecond*256); swf.movieSize.xmax = 20*width; swf.movieSize.ymax = 20*height; @@ -127,27 +262,75 @@ int main (int argc,char ** argv) rgb.b = 0xff; swf_SetRGB(tag,&rgb); + if(stopframe0) { + ActionTAG*action = 0; + tag = swf_InsertTag(tag, ST_DOACTION); + action = action_Stop(action); + action = action_End(action); + swf_ActionSet(tag, action); + swf_ActionFree(action); + + tag = swf_InsertTag(tag, ST_SHOWFRAME); + } + + swf_mp3_bitrate = bitrate; + swf_mp3_out_samplerate = samplerate; + swf_mp3_in_samplerate = samplerate; + if(!definesound) { + int oldframepos=-1, newframepos=0; + float framesamplepos = 0; + float framepos = 0; + float samplepos = 0; + ActionTAG* a = 0; + U16 v1=0,v2=0; tag = swf_InsertTag(tag, ST_SOUNDSTREAMHEAD); - swf_SetSoundStreamHead(tag, blocksize); - - logf(" %d blocks", numsamples/(blocksize*2)); - for(t=0;t %d blocks", numsamples/blocksize); + for(t=0;t Writing block %d", t); - block1 = &samples[t*2*blocksize]; - swf_SetSoundStreamBlock(tag, block1, 1); - tag = swf_InsertTag(tag, ST_SHOWFRAME); + int seek = blocksize - ((int)samplepos - (int)framesamplepos); + + if(newframepos!=oldframepos) { + tag = swf_InsertTag(tag, ST_SOUNDSTREAMBLOCK); + msg(" Starting block %d %d+%d", t, (int)samplepos, (int)blocksize); + block1 = &samples[t*blocksize]; + swf_SetSoundStreamBlock(tag, block1, seek, 1); + v1 = v2 = GET16(tag->data); + } else { + msg(" Adding data...", t); + block1 = &samples[t*blocksize]; + swf_SetSoundStreamBlock(tag, block1, seek, 0); + v1+=v2; + PUT16(tag->data, v1); + } + samplepos += blocksize; + + oldframepos = (int)framepos; + framepos += framesperblock; + newframepos = (int)framepos; + + for(s=oldframepos;s 11025 + swf_SetBlock(tag, samples, numsamples*2); +#endif + + tag = swf_InsertTag(tag, ST_STARTSOUND); swf_SetU16(tag, 24); //id memset(&info, 0, sizeof(info)); @@ -157,9 +340,13 @@ int main (int argc,char ** argv) tag = swf_InsertTag(tag, ST_END); } - f = open(outputname,O_WRONLY|O_CREAT|O_TRUNC, 0644); - if FAILED(swf_WriteSWF(f,&swf)) fprintf(stderr,"WriteSWF() failed.\n"); - close(f); + if(do_cgi) { + if FAILED(swf_WriteCGI(&swf)) fprintf(stderr,"WriteCGI() failed.\n"); + } else { + f = open(outputname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); + if FAILED(swf_WriteSWF(f,&swf)) fprintf(stderr,"WriteSWF() failed.\n"); + close(f); + } swf_FreeTags(&swf); return 0;