00001
00002
00003
00004
00005
00006
00007
00008 #include <qapplication.h>
00009 #include <qfile.h>
00010 #include <qdialog.h>
00011 #include <qcursor.h>
00012 #include <qdir.h>
00013
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <errno.h>
00017 #include <iostream>
00018 #include <math.h>
00019
00020 #ifndef WIN32
00021 #include <netinet/in.h>
00022 #include <linux/soundcard.h>
00023 #include <unistd.h>
00024 #include <fcntl.h>
00025 #include <sys/ioctl.h>
00026 #include <net/if.h>
00027 #include <linux/sockios.h>
00028 #include <mythtv/mythcontext.h>
00029 #include "config.h"
00030 #include "phoneui.h"
00031 #else
00032 #include <io.h>
00033 #include <winsock2.h>
00034 #include <sstream>
00035 #include "gcontext.h"
00036 #endif
00037
00038 #include "webcam.h"
00039 #include "sipfsm.h"
00040 #include "tone.h"
00041
00042 using namespace std;
00043
00044
00045 #ifndef M_PI
00046 #define M_PI 3.1415926
00047 #endif
00048
00049
00050
00051 TelephonyTones::TelephonyTones()
00052 {
00053
00054
00055
00056 Tone oneRing(400, 7000, 400);
00057 oneRing.sum(450, 7000);
00058 Tone silenceA(200);
00059 Tone silenceB(2000);
00060
00061 tone[TONE_RINGBACK] = new Tone(oneRing);
00062 *tone[TONE_RINGBACK] += silenceA;
00063 *tone[TONE_RINGBACK] += oneRing;
00064 *tone[TONE_RINGBACK] += silenceB;
00065
00066
00067 Tone f1(697, 7000, 100);
00068 Tone f2(770, 7000, 100);
00069 Tone f3(852, 7000, 100);
00070 Tone f4(941, 7000, 100);
00071
00072 toneDtmf[0] = new Tone(f4);
00073 toneDtmf[0]->sum(1336, 7000);
00074 toneDtmf[1] = new Tone(f1);
00075 toneDtmf[1]->sum(1209, 7000);
00076 toneDtmf[2] = new Tone(f1);
00077 toneDtmf[2]->sum(1336, 7000);
00078 toneDtmf[3] = new Tone(f1);
00079 toneDtmf[3]->sum(1477, 7000);
00080 toneDtmf[4] = new Tone(f2);
00081 toneDtmf[4]->sum(1209, 7000);
00082 toneDtmf[5] = new Tone(f2);
00083 toneDtmf[5]->sum(1336, 7000);
00084 toneDtmf[6] = new Tone(f2);
00085 toneDtmf[6]->sum(1477, 7000);
00086 toneDtmf[7] = new Tone(f3);
00087 toneDtmf[7]->sum(1209, 7000);
00088 toneDtmf[8] = new Tone(f3);
00089 toneDtmf[8]->sum(1336, 7000);
00090 toneDtmf[9] = new Tone(f3);
00091 toneDtmf[9]->sum(1477, 7000);
00092 toneDtmf[10] = new Tone(f4);
00093 toneDtmf[10]->sum(1209, 7000);
00094 toneDtmf[11] = new Tone(f4);
00095 toneDtmf[11]->sum(1477, 7000);
00096
00097 }
00098
00099 TelephonyTones::~TelephonyTones()
00100 {
00101 for (int i=0; i<12; i++)
00102 delete toneDtmf[i];
00103 delete tone[TONE_RINGBACK];
00104 }
00105
00106 Tone *TelephonyTones::TTone(ToneId Id)
00107 {
00108 if (tone.contains(Id))
00109 return tone[Id];
00110 else
00111 return 0;
00112 }
00113
00114 Tone *TelephonyTones::dtmf(int Id)
00115 {
00116 if (toneDtmf.contains(Id))
00117 return toneDtmf[Id];
00118 else
00119 return 0;
00120 }
00121
00122 Tone::Tone(int freqHz, int volume, int ms, QObject *parent, const char *name) : QObject(parent, name)
00123 {
00124 #ifndef WIN32
00125 mythOutput = 0;
00126 #else
00127 hSpeaker = 0;
00128 #endif
00129 Loop = false;
00130 audioTimer = 0;
00131 Samples = ms * 8;
00132 toneBuffer = new short[Samples];
00133
00134 for (int c=0; c<Samples; c++)
00135 toneBuffer[c] = (short)(sin(c * 2 * M_PI * freqHz / 8000) * volume);
00136 }
00137
00138 Tone::Tone(const Tone &t, QObject *parent, const char *name) : QObject(parent, name)
00139 {
00140 #ifndef WIN32
00141 mythOutput = 0;
00142 #else
00143 hSpeaker = 0;
00144 #endif
00145 Loop = false;
00146 audioTimer = 0;
00147 Samples = t.Samples;
00148 toneBuffer = new short[Samples];
00149 memcpy(toneBuffer, t.toneBuffer, Samples*sizeof(short));
00150 }
00151
00152 Tone::Tone(int ms, QObject *parent, const char *name) : QObject(parent, name)
00153 {
00154 #ifndef WIN32
00155 mythOutput = 0;
00156 #else
00157 hSpeaker = 0;
00158 #endif
00159 Loop = false;
00160 audioTimer = 0;
00161 Samples = ms * 8;
00162 toneBuffer = new short[Samples];
00163 memset(toneBuffer, 0, Samples*sizeof(short));
00164 }
00165
00166 Tone::Tone(wavfile &wav, QObject *parent, const char *name) : QObject(parent, name)
00167 {
00168 #ifndef WIN32
00169 mythOutput = 0;
00170 #else
00171 hSpeaker = 0;
00172 #endif
00173 Loop = false;
00174 audioTimer = 0;
00175 Samples = wav.samples();
00176 toneBuffer = new short[Samples];
00177 memcpy(toneBuffer, wav.getData(), Samples*sizeof(short));
00178 }
00179
00180 Tone::~Tone()
00181 {
00182 Stop();
00183
00184 if (toneBuffer)
00185 delete toneBuffer;
00186 toneBuffer = 0;
00187 }
00188
00189 void Tone::sum(int freqHz, int volume)
00190 {
00191 for (int c=0; c<Samples; c++)
00192 toneBuffer[c] += (short)(sin(c * 2 * M_PI * freqHz / 8000) * volume);
00193 }
00194
00195 Tone& Tone::operator+=(const Tone &rhs)
00196 {
00197 if (rhs.Samples > 0)
00198 {
00199 short *tmp = toneBuffer;
00200 toneBuffer = new short[Samples+rhs.Samples];
00201 memcpy(toneBuffer, tmp, Samples*sizeof(short));
00202 memcpy(&toneBuffer[Samples], rhs.toneBuffer, rhs.Samples*sizeof(short));
00203 Samples += rhs.Samples;
00204 delete tmp;
00205 }
00206 return *this;
00207 }
00208
00209
00210 void Tone::Play(QString deviceName, bool loop)
00211 {
00212 #ifdef WIN32
00213 if (hSpeaker == 0)
00214 {
00215 OpenSpeaker(deviceName);
00216 spkBufferDescr.lpData = (LPSTR)toneBuffer;
00217 spkBufferDescr.dwBufferLength = Samples * sizeof(short);
00218 if (loop)
00219 {
00220 spkBufferDescr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
00221 spkBufferDescr.dwLoops = 0xFFFF;
00222 }
00223 else
00224 {
00225 spkBufferDescr.dwFlags = 0L;
00226 spkBufferDescr.dwLoops = 0L;
00227 }
00228
00229 waveOutPrepareHeader(hSpeaker, &spkBufferDescr, sizeof(WAVEHDR));
00230 waveOutWrite(hSpeaker, &spkBufferDescr, sizeof(WAVEHDR));
00231 }
00232 #else
00233 if (mythOutput == 0)
00234 {
00235 OpenSpeaker(deviceName);
00236 Loop = loop;
00237
00238 if (mythOutput)
00239 {
00240 mythOutput->AddSamples((char *)toneBuffer, Samples, 100);
00241
00242 audioTimer = new QTimer(this);
00243 connect(audioTimer, SIGNAL(timeout()), this, SLOT(audioTimerExpiry()));
00244 audioTimer->start(Samples / 8, true);
00245 }
00246 else
00247 cout << "MythPhone: could not open " << deviceName << " to play tone\n";
00248 }
00249 #endif
00250 }
00251
00252 void Tone::audioTimerExpiry()
00253 {
00254 #ifndef WIN32
00255 if ((Loop) && (mythOutput != 0))
00256 {
00257 mythOutput->AddSamples((char *)toneBuffer, Samples, 100);
00258 audioTimer->start(Samples / 8, true);
00259 }
00260 else
00261 Stop();
00262 #endif
00263 }
00264
00265 void Tone::Stop()
00266 {
00267 if (audioTimer)
00268 {
00269 audioTimer->stop();
00270 delete audioTimer;
00271 audioTimer = 0;
00272 }
00273 CloseSpeaker();
00274 }
00275
00276 void Tone::OpenSpeaker(QString devName)
00277 {
00278 #ifdef WIN32
00279 unsigned int dwResult;
00280
00281
00282 WAVEFORMATEX wfx;
00283 wfx.cbSize = 0;
00284 wfx.nAvgBytesPerSec = 16000;
00285 wfx.nBlockAlign = 2;
00286 wfx.nChannels = 1;
00287 wfx.nSamplesPerSec = 8000;
00288 wfx.wBitsPerSample = 16;
00289 wfx.wFormatTag = WAVE_FORMAT_PCM;
00290
00291 unsigned int SpeakerDevice = WAVE_MAPPER;
00292 WAVEOUTCAPS AudioCap;
00293 int numAudioDevs = waveOutGetNumDevs();
00294 for (int i=0; i<=numAudioDevs; i++)
00295 {
00296 MMRESULT err = waveOutGetDevCaps(i, &AudioCap, sizeof(AudioCap));
00297 if ((err == MMSYSERR_NOERROR) && (devName == AudioCap.szPname))
00298 SpeakerDevice = i;
00299 }
00300
00301 if (dwResult = waveOutOpen(&hSpeaker, SpeakerDevice, &wfx, 0, 0L, WAVE_FORMAT_QUERY))
00302 return;
00303
00304 if (dwResult = waveOutOpen(&hSpeaker, SpeakerDevice, &wfx, 0, 0L, CALLBACK_NULL))
00305 return;
00306
00307 #else
00308 mythOutput = AudioOutput::OpenAudio(devName, "default", 16, 1, 8000,
00309 AUDIOOUTPUT_TELEPHONY, true,
00310 false );
00311 if (mythOutput)
00312 {
00313 mythOutput->SetBlocking(false);
00314 mythOutput->SetEffDsp(8000 * 100);
00315 }
00316 #endif
00317 }
00318
00319 void Tone::CloseSpeaker()
00320 {
00321 #ifdef WIN32
00322 unsigned int dwResult;
00323
00324 if (dwResult = waveOutReset(hSpeaker))
00325 return;
00326
00327 if (dwResult = waveOutUnprepareHeader(hSpeaker, &spkBufferDescr, sizeof(WAVEHDR)))
00328 return;
00329
00330 if (dwResult = waveOutClose(hSpeaker))
00331 return;
00332 hSpeaker = 0;
00333 #else
00334 if (mythOutput)
00335 delete mythOutput;
00336 mythOutput = 0;
00337 #endif
00338 }
00339
00340
00341 bool Tone::Playing()
00342 {
00343 #ifdef WIN32
00344 return (hSpeaker != 0);
00345 #else
00346 return (mythOutput != 0);
00347 #endif
00348 };
00349
00350