Here are my projects completed for ECE 161, Programming languages

Phone Dialer

A simple project to demonstrate writing to “dev/dsp” in a cygwin or linux environment to create sounds. Emulates Dual Tone Multi-Frequency Signaling used by phones.

It can be used instead of dialing on a land line by holding the phones microphone up to the speaker and playing a number.

1-9; A-D: Plays sound when those keys are pressed

I: Dial tone

R: Ringback signal

U: Busy Signal

All frequencies were obtained from the DTMF Wikipedia page

Code


//DTMF dialer
//Jason Schmidt

//includes
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <math.h>
#include <ctype.h>
//constants
#define SAMPLE_RATE 48000
#define PI 3.141592653589793238
#define STRING_SIZE 256
//global variables
int fileDescr;
//frequency matrix
int frq[19][2] = {{1336, 941}, {1209, 697}, {1336, 697}, {1477, 697},
	          {1209, 770}, {1336, 770}, {1477, 770}, {1209, 852},
		  {1336, 852}, {1477, 852}, {1633, 697}, {1633, 770},
		  {1633, 852}, {1633, 941}, {1209, 941}, {1477, 941},
		  {480, 620}, {440, 480}, {350, 440}};
void init_sound(char *dsp_name, int mode, int samp_fmt, int n_chan, int samp_rate)
{
	int	arg;
	if ((fileDescr = open(dsp_name, mode)) < 0)
	{
		printf("Cannot open sound card '%s'\n", dsp_name);
		exit(1);
	}
	arg = samp_fmt;
	if (ioctl(fileDescr, SNDCTL_DSP_SETFMT, &arg) == -1)
	{
		printf("Ioctl error setting sound card sample format\n");
		exit(1);
	}
	if (arg != samp_fmt)
	{
		printf("Sound card cannot be set to %d\n", samp_fmt);
		exit(1);
	}
	arg = n_chan;
	if (ioctl(fileDescr, SNDCTL_DSP_CHANNELS, &arg) == -1)
	{
		printf("Ioctl error setting number of channels\n");
		exit(1);
	}
	if (arg != n_chan)
	{
		printf("Could not set number of channels to %d\n", n_chan);
		exit(1);
	}
	arg = samp_rate;
	if (ioctl(fileDescr, SNDCTL_DSP_SPEED, &arg) == -1)
	{
		printf("Ioctl error setting sample rate\n");
		exit(1);
	}
	if (arg != samp_rate)
	{
		printf("Could not set sample rate to %d\n", samp_rate);
		exit(1);
	}
}
void write_sound(void *data, size_t samp_size, size_t n_samps)
{
	size_t	tmp = samp_size * n_samps;
	if (write(fileDescr, data, tmp) != tmp)
	{
		printf("Write error\n");
		exit(1);
	}
}
void sync_sound(void)
{
	int	tmp = 0;
	if (ioctl(fileDescr, SNDCTL_DSP_SYNC, &tmp) == -1)
	{
		printf("Ioctl error syncing dsp\n");
		exit(1);
	}
}
void close_sound(void)
{
	if (close(fileDescr) < 0)
	{
		printf("Error closing sound card\n");
		exit(1);
	}
}
void play_tone(int button)
{
	unsigned short b[SAMPLE_RATE * 6];
	int j;
	switch (button)
	{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
		case 11:
		case 12:
		case 13:
		case 14:
		case 15:
			for (j = 0; j < SAMPLE_RATE * .4; j++)
				b[j] = 32767/2*sin(2.0*PI*frq[button][0]*j/SAMPLE_RATE) + 
				       32767/2*sin(2.0*PI*frq[button][1]*j/SAMPLE_RATE);
			for (; j < SAMPLE_RATE * .5; j++)
				b[j] = 0;
			write_sound(b, sizeof(short), SAMPLE_RATE / 2);
			break;
		case 16:
			for (j = 0; j < SAMPLE_RATE * .5; j++)
				b[j] = 32767/2*sin(2.0*PI*frq[button][0]*j/SAMPLE_RATE) + 
				       32767/2*sin(2.0*PI*frq[button][1]*j/SAMPLE_RATE);
			for (; j < SAMPLE_RATE * 1; j++)
				b[j] = 0;
			write_sound(b, sizeof(short), SAMPLE_RATE * 1);
			break;
		case 17:
			for (j = 0; j < SAMPLE_RATE * 2; j++)
				b[j] = 32767/2*sin(2.0*PI*frq[button][0]*j/SAMPLE_RATE) + 
				       32767/2*sin(2.0*PI*frq[button][1]*j/SAMPLE_RATE);
			for (; j < SAMPLE_RATE * 6; j++)
				b[j] = 0;
			write_sound(b, sizeof(short), SAMPLE_RATE * 6);
			break;
		case 18:
			for (j = 0; j < SAMPLE_RATE * 3; j++)
				b[j] = 32767/2*sin(2.0*PI*frq[button][0]*j/SAMPLE_RATE) + 
				       32767/2*sin(2.0*PI*frq[button][1]*j/SAMPLE_RATE);
			write_sound(b, sizeof(short), SAMPLE_RATE * 3);
			break;
		case 19:
			for(j = 0; j < SAMPLE_RATE; j++)
				b[j] = 0;
			write_sound(b, sizeof(short), SAMPLE_RATE);
			break;
		case 20:
			for(j = 0; j < SAMPLE_RATE*2; j++)
				b[j] = 0;
			write_sound(b, sizeof(short), SAMPLE_RATE*2);
			break;
	}
}
int main()
{
	char input[STRING_SIZE], ch;
	int error = 0;
	int i;
	init_sound("/dev/dsp", O_WRONLY, AFMT_S16_NE, 1, SAMPLE_RATE);
	fgets(input, STRING_SIZE, stdin);
	if (strlen(input) == STRING_SIZE - 1)
		while ((ch = getchar()) != '\n' && ch != EOF);

	for (i = 0; i < strlen(input) - 1; i++)
	{
		if (error == 1)
			break;
		switch (input[i])
		{
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				play_tone((int)input[i] - 48);
				break;
			case 'A':
			case 'B':
			case 'C':
			case 'D':
				play_tone((int)input[i] - 55);
				break;
			case 'a':
			case 'b':
			case 'c':
			case 'd':
				play_tone((int)input[i] - 87);
				break;
			case 'p':
				play_tone(19);
				break;
			case 'P':
				play_tone(20);
				break;
			case '*':
				play_tone(14);
				break;
			case '#':
				play_tone(15);
				break;
			case 'u':
			case 'U':
				play_tone(16);
				break;
			case 'r':
			case 'R':
				play_tone(17);
				break;
			case 'i':
			case 'I':
				play_tone(18);
				break;
			default:
				error = 1;
				break;
		}
	}
	if (error == 1)
		printf("\nInvalid input");		
	sync_sound();
	close_sound();
	return 0;
}