Skip to content
Snippets Groups Projects
Select Git revision
  • 179ee222650d2cda67ae91aee7640b52c64e619c
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • release/201811
  • release/201808
  • releases/beta1
  • packaging
  • native
  • release-0.2.x
  • 1.0.0
  • 0.2.0
  • 0.1.1
  • 0.1.0
25 results

bezierconnectorwidget.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tonegenerator.cpp 9.36 KiB
    /**
     *  Copyright (C) 2004-2005 Savoir-Faire Linux inc.
     *  Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
     *                                                                              
     *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
     */
    
    #include <math.h>
    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    
    #include "codecDescriptor.h"
    #include "ulaw.h"
    #include "tonegenerator.h"
    #include "../configuration.h"
    #include "../global.h"
    #include "../manager.h"
    #include "../user_cfg.h"
    
    using namespace std;
    
    #define DTMF_FREQ_MIX_RATE	0.45f
    
    ///////////////////////////////////////////////////////////////////////////////
    // ToneThread implementation
    ///////////////////////////////////////////////////////////////////////////////
    ToneThread::ToneThread (Manager *mngr, float32 *buf, int size) {
    	this->mngr = mngr;
    	this->buffer = buf;
    	this->size = size;
    }
    
    ToneThread::~ToneThread (void) {
    	this->terminate();
    }
    
    void
    ToneThread::run (void) {
    	while (mngr->getTonezone()) {
    		if (mngr->getAudioDriver()->mydata.dataFilled >= 
    				mngr->getAudioDriver()->mydata.dataToAddRem) {
    			mngr->getAudioDriver()->mydata.dataFilled = 0;
    		}
    	}
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // ToneGenerator implementation
    ///////////////////////////////////////////////////////////////////////////////
    
    ToneGenerator::ToneGenerator (Manager *mngr) {	
    	this->initTone();
    	this->manager = mngr;
    	buf = new float32[SIZEBUF];	
    	tonethread = NULL;
    }
    
    ToneGenerator::ToneGenerator () {	
    	this->initTone();	
    	tonethread = NULL;
    }
    
    ToneGenerator::~ToneGenerator (void) {
    	delete[] buf;
    	delete tonethread;
    }
    
    /**
     * Initialisation of ring tone for supported zone
     */
    void
    ToneGenerator::initTone (void) {
    	toneZone[ID_NORTH_AMERICA][ZT_TONE_DIALTONE] = "350+440";
    	toneZone[ID_NORTH_AMERICA][ZT_TONE_BUSY] = "480+620/500,0/500";
    	toneZone[ID_NORTH_AMERICA][ZT_TONE_RINGTONE] = "440+480/2000,0/4000";
    	toneZone[ID_NORTH_AMERICA][ZT_TONE_CONGESTION] = "480+620/250,0/250"; 
    
    	toneZone[ID_FRANCE][ZT_TONE_DIALTONE] = "440";
    	toneZone[ID_FRANCE][ZT_TONE_BUSY] = "440/500,0/500";
    	toneZone[ID_FRANCE][ZT_TONE_RINGTONE] = "440/1500,0/3500";
    	toneZone[ID_FRANCE][ZT_TONE_CONGESTION] = "440/250,0/250";
    	
    	toneZone[ID_AUSTRALIA][ZT_TONE_DIALTONE] = "413+438";
    	toneZone[ID_AUSTRALIA][ZT_TONE_BUSY] = "425/375,0/375";
    	toneZone[ID_AUSTRALIA][ZT_TONE_RINGTONE] = 
    		"413+438/400,0/200,413+438/400,0/2000";
    	toneZone[ID_AUSTRALIA][ZT_TONE_CONGESTION] = "425/375,0/375,420/375,8/375"; 
    	
    	toneZone[ID_UNITED_KINGDOM][ZT_TONE_DIALTONE] = "350+440";
    	toneZone[ID_UNITED_KINGDOM][ZT_TONE_BUSY] = "400/375,0/375";
    	toneZone[ID_UNITED_KINGDOM][ZT_TONE_RINGTONE] = 
    		"400+450/400,0/200,400+450/400,0/2000";
    	toneZone[ID_UNITED_KINGDOM][ZT_TONE_CONGESTION] = 
    		"400/400,0/350,400/225,0/525";
    	
    	toneZone[ID_SPAIN][ZT_TONE_DIALTONE] = "425";
    	toneZone[ID_SPAIN][ZT_TONE_BUSY] = "425/200,0/200";
    	toneZone[ID_SPAIN][ZT_TONE_RINGTONE] = "425/1500,0/3000";
    	toneZone[ID_SPAIN][ZT_TONE_CONGESTION] = 
    		"425/200,0/200,425/200,0/200,425/200,0/600";
    	
    	toneZone[ID_ITALY][ZT_TONE_DIALTONE] = "425/600,0/1000,425/200,0/200";
    	toneZone[ID_ITALY][ZT_TONE_BUSY] = "425/500,0/500";
    	toneZone[ID_ITALY][ZT_TONE_RINGTONE] = "425/1000,0/4000";
    	toneZone[ID_ITALY][ZT_TONE_CONGESTION] = "425/200,0/200";
    	
    	toneZone[ID_JAPAN][ZT_TONE_DIALTONE] = "400";
    	toneZone[ID_JAPAN][ZT_TONE_BUSY] = "400/500,0/500";
    	toneZone[ID_JAPAN][ZT_TONE_RINGTONE] = "400+15/1000,0/2000";
    	toneZone[ID_JAPAN][ZT_TONE_CONGESTION] = "400/500,0/500";
    }
    
    /**
     * Calculate superposition of 2 sinus 
     *
     * @param	lower frequency
     * @param	higher frequency
     * @param	samplingRate
     * @param	ptr for result buffer
     */
    void
    ToneGenerator::generateSin (int lowerfreq, int higherfreq, 
    												int samplingRate, float32*ptr) {
    	double var1, var2;
    													
    	var1 = (double)2 * (double)M_PI * (double)higherfreq / (double)samplingRate; 
    	var2 = (double)2 * (double)M_PI * (double)lowerfreq / (double)samplingRate;
    	
    	for(int t = 0; t < samplingRate; t++) {
    		ptr[t] = DTMF_FREQ_MIX_RATE * (float32)(sin(var1 * t) + sin(var2 * t));
    	}
    }
    
    /**
     * Build tone according to the id-zone, with initialisation of ring tone.
     * Generate sinus with frequencies alternatively by time
     *
     * @param	idCountry		
     * @param	idTones			
     * @param 	samplingRate	
     * @param	ns				section number of format tone
     */
    void
    ToneGenerator::buildTone (int idCountry, int idTones, int samplingRate, 
    							float32* temp) {
    	string s;
    	int count = 0;
    	int	byte = 0,
    		byte_temp = 0;
    	static int	nbcomma = 0;
    	float32 *buffer = new float32[SIZEBUF];
    	int pos;
    
    	string str(toneZone[idCountry][idTones]);
    	nbcomma = contains(toneZone[idCountry][idTones], ',');
    
    	// Number of format sections 
    	for (int i = 0; i < nbcomma + 1; i++) {
    		pos = str.find(',');
    		s = str.substr(0, pos);
    		pos = s.find('+');
    		freq1 = atoi((s.substr(0, pos)).data());
    		freq2 = atoi((s.substr(pos + 1, s.find('/'))).data());
    		pos = s.find('/');
    		time = atoi((s.substr(pos + 1, s.length())).data());
    		
    		// Generate sinus, buffer is the result
    		generateSin(freq1, freq2, samplingRate, buffer);
    		
    		// If there is time or if it's unlimited
    		if (time) {
    			byte = (samplingRate*2*time)/1000;
    		} else {
    			byte = samplingRate;
    		}
    		
    		// To concatenate the different buffers for each section.
    		for (int j = byte_temp * i; j < byte + (byte_temp * i); j++) {
    			temp[j] = buffer[count++];
    		}		
    		byte_temp = byte;
    		count = 0;
    		
    		str = str.substr(str.find(',') + 1, str.length());
    	}
    	// Total number in final buffer
    	totalbytes = byte + (byte_temp * (nbcomma+1));
    	delete[] buffer;
    }
    
    /**
     * Returns id selected zone for tone choice
     * 
     * @param	name of the zone
     * @return	id of the zone
     */
    int
    ToneGenerator::idZoneName (const string& name) {
    	if (name.compare("North America") == 0) {
    		return ID_NORTH_AMERICA;
    	} else if (name.compare("France") == 0) {
    		return ID_FRANCE;
    	} else if (name.compare("Australia") == 0) {
    		return ID_AUSTRALIA;
    	} else if (name.compare("United Kingdom") == 0) {
    		return ID_UNITED_KINGDOM;
    	} else if (name.compare("Spain") == 0) {
    		return ID_SPAIN;
    	} else if (name.compare("Italy") == 0) {
    		return ID_ITALY;
    	} else if (name.compare("Japan") == 0) {
    		return ID_JAPAN;
    	} else {
    		_debug("Zone no supported\n");
    		return -1;
    	}
    }
    
    /**
     * Handle the required tone 
     *  
     * @param	idr: specified tone
     * @param	var: indicates begin/end of the tone
     */
    void
    ToneGenerator::toneHandle (int idr) {
    	int idz = idZoneName(get_config_fields_str(PREFERENCES, ZONE_TONE));
    	
    	if (idz != -1) {
    		buildTone (idz, idr, SAMPLING_RATE, buf);
    
    		manager->getAudioDriver()->mydata.dataToAdd = buf;
    		manager->getAudioDriver()->mydata.dataToAddRem = totalbytes;
    		
    		// New thread for the tone
    		if (tonethread == NULL) {
    			tonethread = new ToneThread (manager, buf, totalbytes);
    			if (!manager->getAudioDriver()->isStreamActive()) {
    				manager->getAudioDriver()->startStream();
    			}
    			tonethread->start();
    		}
    
    		if (!manager->getTonezone()) {
    			manager->getAudioDriver()->stopStream();
    			if (tonethread != NULL) {	
    				delete tonethread;
    				tonethread = NULL;
    			}
    		}
    	}
    }
    
    
    int
    ToneGenerator::playRingtone (const char *fileName) {
    	short* dst = NULL;
    	float32* floatdst = NULL;
    	char* src = NULL;
    	int expandedsize, length;
    	Ulaw* ulaw = new Ulaw (PAYLOAD_CODEC_ULAW, CODEC_ULAW);
    
    	if (fileName == NULL) {
    		return 0;
    	}
    	
    	fstream file;
    	file.open(fileName, fstream::in);
    	if (!file.is_open()) {
    		return 0;
      	}
    
    	// get length of file:
      	file.seekg (0, ios::end);
      	length = file.tellg();
      	file.seekg (0, ios::beg);
    
      	// allocate memory:
      	src = new char [length];
    	dst = new short[length*2];
    	
      	// read data as a block:
      	file.read (src,length);
    	
    	// Decode file.ul
    	expandedsize = ulaw->codecDecode (dst, (unsigned char *)src, length);
    	
    	floatdst = new float32[expandedsize];
    	ulaw->int16ToFloat32 (dst, floatdst, expandedsize);
    	
    	manager->getAudioDriver()->mydata.dataToAdd = floatdst;
    	manager->getAudioDriver()->mydata.dataToAddRem = expandedsize;
    	
    	// Start tone thread
    	if (tonethread == NULL) {
    		tonethread = new ToneThread (manager, floatdst, expandedsize);
    		if (!manager->getAudioDriver()->isStreamActive()) {
    			manager->getAudioDriver()->startStream();
    		}
    		tonethread->start();
    	}
    	if (!manager->getTonezone()) {
    		manager->getAudioDriver()->stopStream();
    		if (tonethread != NULL) {	
    			delete tonethread;
    			tonethread = NULL;
    			delete[] dst;
    			delete[] src;
    			delete[] floatdst;
    		}
    	}
    	file.close();
    	return 1;
    }
    
    int
    ToneGenerator::contains (const string& str, char c)
    {
    	static int nb = 0;
    	
    	unsigned int pos = str.find(c);
    	if (pos != string::npos) {
    		nb = nb + 1;
    		return contains(str.substr(pos + 1, str.length()), c);
    	} else {
    		return nb;
    	}
    
    }