home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
550b.lha
/
Term_v1.8a
/
Source.LZH
/
ToneDial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-07
|
6KB
|
315 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
*
* Touch-tone period & cycle values are
*
* (C) Copyright 1989 by Commodore-Amiga, Inc.
*
* Name .....: ToneDial.c
* Created ..: Wednesday 03-Jul-91 10:38
* Revision .: 0
*
* Date Author Comment
* ========= ======== ====================
* 03-Jul-91 Olsen Created this file!
*
* $Revision Header ********************************************************/
#include "TermGlobal.h"
/* Audio device control. */
STATIC struct IOAudio *Audio,
*Audio1,
*Audio2;
/* A couple of reply ports. */
STATIC struct MsgPort *AudioPort,
*Audio1Port,
*Audio2Port;
/* Channel allocation scheme is as follow:
*
* - allocate two channels either on the right or
* the left side.
*
* - if this fails, allocate two different stereo
* channels.
*/
STATIC UBYTE Channels[] =
{
1 | 8,
2 | 4,
1 | 4,
2 | 8
};
/* Cheapo square wave. */
STATIC BYTE __chip SquareWave[8] =
{
0,127,127,0,0,-127,-127,0
};
/* Touch tone periods for NTSC machines. */
STATIC USHORT NTSC_Periods[16][2] =
{
{ 475,335 }, /* 0 */
{ 642,370 }, /* 1 */
{ 642,335 }, /* 2 */
{ 642,303 }, /* 3 */
{ 581,370 }, /* 4 */
{ 581,335 }, /* 5 */
{ 581,303 }, /* 6 */
{ 525,370 }, /* 7 */
{ 525,335 }, /* 8 */
{ 525,303 }, /* 9 */
{ 475,370 }, /* * */
{ 475,303 }, /* # */
{ 642,274 }, /* A */
{ 581,274 }, /* B */
{ 525,274 }, /* C */
{ 475,274 }, /* D */
};
/* Touch tone periods for PAL machines. */
STATIC USHORT PAL_Periods[16][2] =
{
{ 471,332 }, /* 0 */
{ 636,367 }, /* 1 */
{ 636,332 }, /* 2 */
{ 636,300 }, /* 3 */
{ 576,367 }, /* 4 */
{ 576,332 }, /* 5 */
{ 576,300 }, /* 6 */
{ 520,367 }, /* 7 */
{ 520,332 }, /* 8 */
{ 520,300 }, /* 9 */
{ 471,367 }, /* * */
{ 471,300 }, /* # */
{ 636,271 }, /* A */
{ 576,271 }, /* B */
{ 520,271 }, /* C */
{ 471,271 } /* D */
};
/* Length of each tone given in audio cycles. */
USHORT Cycles[16][2] =
{
{ 106,150 }, /* 0 */
{ 96,166 }, /* 1 */
{ 106,204 }, /* 2 */
{ 118,250 }, /* 3 */
{ 96,150 }, /* 4 */
{ 106,184 }, /* 5 */
{ 118,226 }, /* 6 */
{ 96,136 }, /* 7 */
{ 106,166 }, /* 8 */
{ 118,204 }, /* 9 */
{ 96,124 }, /* * */
{ 118,186 }, /* # */
{ 130,304 }, /* A */
{ 130,276 }, /* B */
{ 130,250 }, /* C */
{ 130,226 } /* D */
};
/* The tone codes we know. */
UBYTE *Codes = "0123456789*#ABCD";
/* DeleteTone():
*
* Free the resources allocated for touch-tone dialing.
*/
VOID
DeleteTone()
{
if(Audio2)
{
FreeVec(Audio2);
Audio2 = NULL;
}
if(Audio2Port)
{
DeleteMsgPort(Audio2Port);
Audio2Port = NULL;
}
if(Audio1)
{
FreeVec(Audio1);
Audio1 = NULL;
}
if(Audio1Port)
{
DeleteMsgPort(Audio1Port);
Audio1Port = NULL;
}
if(Audio)
{
if(Audio -> ioa_Request . io_Device)
CloseDevice(Audio);
DeleteIORequest(Audio);
Audio = NULL;
}
if(AudioPort)
{
DeleteMsgPort(AudioPort);
AudioPort = NULL;
}
}
/* CreateTone():
*
* Allocate the resources required for touch-tone dialing.
*/
STATIC BYTE
CreateTone()
{
if(AudioPort = CreateMsgPort())
{
if(Audio = (struct IOAudio *)CreateIORequest(AudioPort,sizeof(struct IOAudio)))
{
Audio -> ioa_Request . io_Message . mn_Node . ln_Pri = 10;
Audio -> ioa_Data = Channels;
Audio -> ioa_Length = sizeof(Channels);
if(!OpenDevice(AUDIONAME,0,Audio,0))
{
Audio -> ioa_Request . io_Command = CMD_WRITE;
Audio -> ioa_Request . io_Flags = ADIOF_PERVOL;
Audio -> ioa_Data = SquareWave;
Audio -> ioa_Length = 8;
Audio -> ioa_Volume = 32;
if(Audio1Port = CreateMsgPort())
{
if(Audio1 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_PUBLIC))
{
CopyMem(Audio,Audio1,sizeof(struct IOAudio));
Audio1 -> ioa_Request . io_Message . mn_ReplyPort = Audio1Port;
Audio1 -> ioa_Request . io_Unit = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD0|DMAF_AUD1));
if(Audio2Port = CreateMsgPort())
{
if(Audio2 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_PUBLIC))
{
CopyMem(Audio,Audio2,sizeof(struct IOAudio));
Audio2 -> ioa_Request . io_Message . mn_ReplyPort = Audio2Port;
Audio2 -> ioa_Request . io_Unit = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD2|DMAF_AUD3));
return(TRUE);
}
}
}
}
}
}
DeleteTone();
}
return(FALSE);
}
/* ToneDial(UBYTE *Number):
*
* Dial a number using touch-tone coding, produce the
* sounds using the Amiga audio hardware.
*/
BYTE
ToneDial(UBYTE *Number)
{
SHORT i,j;
/* Resources ready? */
if(!Audio)
{
if(!CreateTone())
return(FALSE);
}
/* Check TV system (i.e. crystal frequency). */
if(GfxBase -> DisplayFlags & PAL)
{
for(i = 0 ; i < strlen(Number) ; i++)
{
for(j = 0 ; j < 16 ; j++)
{
if(ToUpper(Number[i]) == Codes[j])
{
Audio1 -> ioa_Cycles = Cycles[j][0];
Audio1 -> ioa_Period = PAL_Periods[j][0];
Audio2 -> ioa_Period = PAL_Periods[j][1];
Audio2 -> ioa_Cycles = Cycles[j][1];
BeginIO(Audio1);
BeginIO(Audio2);
WaitIO(Audio1);
WaitIO(Audio2);
Delay(4);
break;
}
}
}
}
else
{
for(i = 0 ; i < strlen(Number) ; i++)
{
for(j = 0 ; j < 16 ; j++)
{
if(Number[i] == Codes[j])
{
Audio1 -> ioa_Cycles = Cycles[j][0];
Audio1 -> ioa_Period = NTSC_Periods[j][0];
Audio2 -> ioa_Cycles = Cycles[j][1];
Audio2 -> ioa_Period = NTSC_Periods[j][1];
BeginIO(Audio1);
BeginIO(Audio2);
WaitIO(Audio1);
WaitIO(Audio2);
Delay(4);
break;
}
}
}
}
return(TRUE);
}