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 --- kscd/kscdmagic/sound.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 kscd/kscdmagic/sound.cpp (limited to 'kscd/kscdmagic/sound.cpp') diff --git a/kscd/kscdmagic/sound.cpp b/kscd/kscdmagic/sound.cpp new file mode 100644 index 00000000..0bcb8d8d --- /dev/null +++ b/kscd/kscdmagic/sound.cpp @@ -0,0 +1,252 @@ +/* Synaesthesia - program to display sound graphically + Copyright (C) 1997 Paul Francis Harrison + + 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. + + The author may be contacted at: + pfh@yoyo.cc.monash.edu.au + or + 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia +*/ + +#if defined(__linux__) || defined(__svr4__) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (__linux__) +#include +#ifndef __GNUC__ +#define __GNUC__ 1 +#endif +#undef __STRICT_ANSI__ +#include +#include +#endif + +#if defined (__svr4__) +#include +#endif + + +// who knows when we'll need that... +#if defined (FreeBSD) +#include +#include +#define CDROM_LEADOUT 0xAA +#define CD_FRAMES 75 /* frames per second */ +#define CDROM_DATA_TRACK 0x4 +#endif + +#include + +#include +#include +#include +#include "syna.h" +#include "magicconf.h" + + +/* Sound Recording ================================================= */ + +#ifdef LITTLEENDIAN +#define SOUNDFORMAT AFMT_S16_LE +#else +#define SOUNDFORMAT AFMT_S16_BE +#endif + +//If kernel starts running out of sound memory playing mp3s, this could +//be the problem. OTOH if it is too small, it will start ticking on slow +//computers +#define MAXWINDOWSIZE 32 + +static SoundSource source; +static int inFrequency, downFactor, windowSize, pipeIn, device; +static short *dataIn; +static char *mixer; + +void +openSound(SoundSource source, int inFrequency, const char *dspName, + char *mixerName) +{ + ::source = source; + ::inFrequency = inFrequency; + ::windowSize = 1; + mixer = mixerName; + downFactor = inFrequency / frequency; + if (downFactor <= 0) + downFactor = 1; + + int format, stereo, fragment, fqc; + +#ifdef __FreeBSD__ + attempt(device = open(dspName,O_WRONLY),"opening dsp device",true); + format = SOUNDFORMAT; + attempt(ioctl(device,SNDCTL_DSP_SETFMT,&format),"setting format",true); + if (format != SOUNDFORMAT) error("setting format (2)"); + close(device); +#endif + if (source == SourcePipe) + attempt(device = open(dspName,O_WRONLY),"opening dsp device",true); + else + attempt(device = open(dspName,O_RDONLY),"opening dsp device",true); + + //Probably not needed + //attemptNoDie(ioctl(device,SNDCTL_DSP_RESET,0),"reseting dsp"); + format = SOUNDFORMAT; + fqc = (source == SourcePipe ? inFrequency : frequency); + stereo = 1; + + //int logWindowSize = -1, tmp = windowSize*downFactor; + //while(tmp) { + // tmp /= 2; + // logWindowSize++; + //} + + if (source == SourcePipe) + //fragment = 0x00020000 + (m-overlap+1)+logWindowSize; + fragment = 0x00010000*(MAXWINDOWSIZE+1) + (m-overlap+1);//+logWindowSize; + //Soundcard should read in windowSize + // blocks of sound before blocking + else + //fragment = 0x00020000 + (m-overlap+1); //2 fragments of size 2*(2^(m-overlap+1)) bytes + + //Added extra fragments to allow recording overrun (9/7/98) + fragment = 0x00080000 + (m-overlap+1); //8 fragments of size 2*(2^(m-overlap+1)) bytes + + + + + //Was 0x00010000 + m; + + attemptNoDie(ioctl(device,SNDCTL_DSP_SETFRAGMENT,&fragment),"setting fragment",true); +#ifndef __FreeBSD__ + attempt(ioctl(device,SNDCTL_DSP_SETFMT,&format),"setting format",true); + if (format != SOUNDFORMAT) error("setting format (2)"); +#endif + attempt(ioctl(device,SNDCTL_DSP_STEREO,&stereo),"setting stereo",true); + attemptNoDie(ioctl(device,SNDCTL_DSP_SPEED,&fqc),"setting frequency",true); + + data = new short[n*2]; + + if (source == SourcePipe) { + dataIn = new short[n*2*downFactor*MAXWINDOWSIZE]; + memset(dataIn,0,n*4*downFactor*MAXWINDOWSIZE); + pipeIn = dup(0); + close(0); + } +} + +void closeSound() { + delete data; + if (source == SourcePipe) { + delete dataIn; + close(pipeIn); + } + close(device); +} + +int readWholeBlock(int pipe,char *dest,int length) { + while(length > 0) { + int result = read(pipe,dest,length); + if (result < 1) + return -1; + dest += result; + length -= result; + } + return 0; +} + +int getNextFragment(void) { + if (source == SourcePipe) { + static int lastTime = 0; + int nowTime; + timeval timeVal1, timeVal2; + + gettimeofday(&timeVal1,0); + write(device, (char*)dataIn, n*4*downFactor*windowSize); + gettimeofday(&timeVal2,0); + + nowTime = timeVal1.tv_usec + timeVal1.tv_sec * 1000000; + if (nowTime > lastTime) { + int optimumFrags = + int(double(nowTime-lastTime)*inFrequency/1000000.0/(n*downFactor)) + +1; + if (optimumFrags > MAXWINDOWSIZE) + optimumFrags = MAXWINDOWSIZE; + + windowSize = optimumFrags; + } + + lastTime = timeVal2.tv_usec + timeVal2.tv_sec * 1000000; + + if (readWholeBlock(pipeIn, ((char*)dataIn), n*4*downFactor*windowSize) == -1) + return -1; + + int i,j; + for(i=0,j=0;i 8 || info.blocks < 1) /* Sanity check */ + info.blocks = 1; + + for(i=0;i