From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- arts/modules/synth/synth_capture_wav_impl.cc | 169 +++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 arts/modules/synth/synth_capture_wav_impl.cc (limited to 'arts/modules/synth/synth_capture_wav_impl.cc') diff --git a/arts/modules/synth/synth_capture_wav_impl.cc b/arts/modules/synth/synth_capture_wav_impl.cc new file mode 100644 index 00000000..15416761 --- /dev/null +++ b/arts/modules/synth/synth_capture_wav_impl.cc @@ -0,0 +1,169 @@ + /* + + Copyright (C) 2000, 2001 Stefan Westerfeld + stefan@space.twc.de, Matthias Kretz + + 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 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 "artsmodulessynth.h" +#include "convert.h" +#include "mcoputils.h" +#include "stdsynthmodule.h" +#include "debug.h" +#include +#include +#include + +using namespace std; +namespace Arts { + +class Synth_CAPTURE_WAV_impl :virtual public Synth_CAPTURE_WAV_skel, + virtual public StdSynthModule +{ + bool audioinit, scaleerr, running; + int audiofd, byteorder, v,datalen,channels; + + unsigned char *outblock; + unsigned long maxsamples; + + string _filename; + +/**** + + WAV writing code and header taken from kwave. Many thanks go to + Martin Wilz who has written this ;) + + ****/ + + struct wavheader + { + char riffid[4]; + long filelength; + char wavid[4]; + char fmtid[4]; + long fmtlength; + short int mode; + short int channels; + long rate; + long AvgBytesPerSec; + short int BlockAlign; + short int bitspersample; + } header; + +public: + Synth_CAPTURE_WAV_impl(); + void streamInit(); + void calculateBlock(unsigned long samples); + void streamEnd(); + string filename() { return _filename; } + void filename( const string &newFilename ); +}; + +Synth_CAPTURE_WAV_impl::Synth_CAPTURE_WAV_impl() + : running(false), _filename( "capture" ) +{ +} + +void Synth_CAPTURE_WAV_impl::streamInit() +{ + /* + * we use createFilePath to prevent the usual symlink security issues + * in /tmp - add .wav manually as createFilePath substitutes . with _ + */ + string filename = MCOPUtils::createFilePath(_filename)+ ".wav"; + audiofd = open(filename.c_str(),O_WRONLY|O_CREAT|O_TRUNC,0644); + +/* write header */ + + int rate=44100; + int bit=16; + + channels = 2; /* hardcoded here - make it a parameter? */ + + arts_info("capturing output to %s", filename.c_str()); + datalen=0; + + strncpy (header.riffid,"RIFF",4); + strncpy (header.wavid,"WAVE",4); + strncpy (header.fmtid,"fmt ",4); + header.fmtlength=16; + header.filelength=sizeof(struct wavheader); + header.mode=1; + header.channels=channels; + header.rate=rate; + header.AvgBytesPerSec=rate*bit/8; + header.BlockAlign=channels*bit/8; + header.bitspersample=bit; + + write(audiofd,&header,sizeof (struct wavheader)); + write(audiofd,"data",4); + write(audiofd,&datalen,4); + + maxsamples = 0; + outblock = 0; + v = 0; + running = true; +} + +void Synth_CAPTURE_WAV_impl::calculateBlock(unsigned long samples) +{ + if(samples > maxsamples) + { + maxsamples = samples; + outblock = (unsigned char *)realloc(outblock, maxsamples * 4); + // 2 channels, 16 bit + } + + if(channels == 1) + convert_mono_float_16le(samples,left,outblock); + + if(channels == 2) + convert_stereo_2float_i16le(samples,left,right,outblock); + + write(audiofd,outblock,samples*channels*2); + datalen += samples*channels*2; +} + +void Synth_CAPTURE_WAV_impl::streamEnd() +{ +/* rewrite header which now contains the correct size of the file */ + lseek(audiofd,0,SEEK_SET); + header.filelength=sizeof(struct wavheader)+datalen; + write(audiofd,&header,sizeof (struct wavheader)); + write(audiofd,"data",4); + write(audiofd,&datalen,4); + + close(audiofd); + + running = false; +} +void Synth_CAPTURE_WAV_impl::filename( const string &newFilename ) +{ + if(_filename != newFilename) { + _filename = newFilename; + if(running) + { + streamEnd(); + streamInit(); + } + filename_changed(newFilename); + } +} + +REGISTER_IMPLEMENTATION(Synth_CAPTURE_WAV_impl); + +} -- cgit v1.2.1