diff options
Diffstat (limited to '')
-rw-r--r-- | private/mvdm/softpc.new/host/src/nt_sound.c | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/host/src/nt_sound.c b/private/mvdm/softpc.new/host/src/nt_sound.c new file mode 100644 index 000000000..10cc043ef --- /dev/null +++ b/private/mvdm/softpc.new/host/src/nt_sound.c @@ -0,0 +1,420 @@ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddbeep.h> +#include <windows.h> +#include "insignia.h" +#include "host_def.h" +/* + * VPC-XT Revision 2.0 + * + * Title : sg_sound.c + * + * Description : This module provides functions to control sound. The + * functions are defined: + * + * host_ring_bell(duration) + * host_alarm(duration) + * host_timer2_waveform(delay,lowclocks,hiclocks,lohi,repeat) + * host_enable_timer2_sound() + * host_disable_timer2_sound() + * + * Author : + * + * Notes : + */ + +#include "xt.h" +#include "config.h" +#include "debug.h" +#include "error.h" +#include <stdio.h> +#include "trace.h" +#include "video.h" +#include "debug.h" + + +IMPORT ULONG GetPerfCounter(VOID); + +ULONG FreqT2 = 0; +BOOL PpiState = FALSE; +BOOL T2State = FALSE; +ULONG LastPpi = 0; +ULONG FreqPpi = 0; +ULONG ET2TicCount=0; +ULONG PpiCounting = 0; + +HANDLE hBeepDevice = 0; +ULONG BeepCloseCount = 0; +ULONG BeepLastFreq = 0; +ULONG BeepLastDuration = 0; + + +// human frequency audible sound range +#define AUDIBLE_MIN 10 +#define AUDIBLE_MAX 20000 +#define CLICK 100 + +VOID LazyBeep(ULONG Freq, ULONG Duration); +void PulsePpi(void); + +/*============================================================================ + + host_alarm - ring bell irrespective of configuration (used on keyboard + buffer overflow for example). + +=============================================================================*/ + +void host_alarm(duration) +long int duration; +{ +MessageBeep(MB_OK); +} + +/*======================================================================== + + host_ring_bell - ring bell if configured (used by video on output + of ^G, for example). + +=========================================================================*/ + +void host_ring_bell(duration) +long int duration; +{ +if( host_runtime_inquire(C_SOUND_ON)) + { + host_alarm(duration); + } +} + + + /* assumes caller holds ica lock */ + +VOID InitSound( BOOL bInit) +{ + if (!bInit) { + host_ica_lock(); + LazyBeep(0L, 0L); + if (hBeepDevice && hBeepDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hBeepDevice); + hBeepDevice = 0; + } + host_ica_unlock(); + return; + } +} + + +HANDLE OpenBeepDevice(void) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING NameString; + NTSTATUS Status; + IO_STATUS_BLOCK IoStatus; + HANDLE hBeep; + + RtlInitUnicodeString( &NameString, DD_BEEP_DEVICE_NAME_U ); + InitializeObjectAttributes( &ObjectAttributes, + &NameString, + 0, + NULL, + NULL + ); + + Status = NtCreateFile( &hBeep, + FILE_READ_DATA | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatus, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + 0, + (PVOID) NULL, + 0 + ); + + if (!NT_SUCCESS( Status )) { +#ifndef PROD + printf("NTVDM: OpenBeepDevice Status=%lx\n",Status); +#endif + hBeep = INVALID_HANDLE_VALUE; + } + + + return hBeep; +} + + + + +/* + * LazyBeep - + * Calls Beep Device Driver asynchronously + * + * Acceptable parameters are: + * (Freq,Dur) Action + * (0,0) - stop sound + * (nonzero, INFINITE) - play a freq + * + * not multithreaded safe + * + */ +VOID LazyBeep(ULONG Freq, ULONG Duration) +{ + IO_STATUS_BLOCK IoStatus; + BEEP_SET_PARAMETERS bps; + + if (Freq != BeepLastFreq || Duration != BeepLastDuration) { + bps.Frequency = Freq; + bps.Duration = Duration; + + // + // If the duration is < 10 ms, then we assume sound is being + // off so remember the state as 0,0 so that we won't turn it + // off again. + // + if (Duration < 10) { + BeepLastFreq = 0; + BeepLastDuration = 0; + } + else { + BeepLastFreq = Freq; + BeepLastDuration = Duration; + } + + if (!hBeepDevice) { + hBeepDevice = OpenBeepDevice(); + } + + if (hBeepDevice == INVALID_HANDLE_VALUE) { + return; + } + + NtDeviceIoControlFile( hBeepDevice, + NULL, + NULL, + NULL, + &IoStatus, + IOCTL_BEEP_SET, + &bps, + sizeof(bps), + NULL, + 0 + ); + + BeepCloseCount = 1000; + + } + + +} + + + + + +/* + * PlaySound + */ +void PlaySound(BOOL bPulsedPpi) +{ + if (PpiState && T2State && FreqT2) { + LazyBeep(FreqT2, INFINITE); + } + else if (FreqPpi > AUDIBLE_MIN) { + LazyBeep(FreqPpi,INFINITE); + } + else if (bPulsedPpi && PpiCounting) { + LazyBeep(CLICK,1); + } + else { + LazyBeep(0,0); + } +} + + + + +/* + * host_timer2_waveform - output specified sound waveform + * assumes caller holds ica lock (see base\timer.c) + */ +void host_timer2_waveform(int delay, + ULONG loclocks, + ULONG hiclocks, + int lohi, + int repeat) +{ + ULONG ul; + + if (loclocks == INFINITE || hiclocks == INFINITE) { + FreqT2 = 0; + } + else { + ul = loclocks + hiclocks; + if (!ul) + ul++; + FreqT2 = 1193180/ul; + + if (FreqT2 >= AUDIBLE_MAX) { + hiclocks = INFINITE; + FreqT2 = 0; + } + else if (FreqT2 <= AUDIBLE_MIN) { + loclocks = INFINITE; + FreqT2 = 0; + } + } + + PlaySound(FALSE); +} + + + +/* + * Updates the hosts Ppi sound state + */ +void HostPpiState(BYTE PortValue) +{ + BOOL bPpi; + + host_ica_lock(); + + T2State = PortValue & 1 ? TRUE: FALSE; + bPpi = PortValue & 2 ? TRUE: FALSE; + + if (bPpi != PpiState) { + PpiState = bPpi; + if (PpiState) { + PulsePpi(); + } + + PlaySound(PpiState); + } + + host_ica_unlock(); +} + + + + +void PulsePpi(void) +{ + static ULONG PpiTicStart=0; + static ULONG PpiCycles =0; + ULONG ul,Elapsed; + ULONG PrevTicCount; + + + PrevTicCount = ET2TicCount; + ET2TicCount = GetTickCount(); + Elapsed = ET2TicCount > PrevTicCount + ? ET2TicCount - PrevTicCount + : 0xFFFFFFFF - ET2TicCount + PrevTicCount; + + if (Elapsed > 200) { + if (PpiCounting) { + PpiCounting = 0; + LastPpi = 0; + FreqPpi = 0; + } + return; + } + + + if (!PpiCounting) { + PpiCounting = GetPerfCounter(); + PpiCycles = 0; + LastPpi = 0; + FreqPpi = 0; + PpiTicStart = ET2TicCount; + return; + } + + if (PpiTicStart + 200 >= ET2TicCount) { + PpiCycles++; + return; + } + + + ul = GetPerfCounter(); + Elapsed = ul >= PpiCounting + ? ul - PpiCounting + : 0xFFFFFFFF - PpiCounting + ul; + if (!Elapsed) // insurance! + Elapsed++; + PpiCounting = ul; + PpiTicStart = ET2TicCount; + + /* + * Calculate the new avergae Ppi, rounding off to keep + * signal from wavering. + */ + ul = (10000 * PpiCycles)/Elapsed; + if ((ul & 0x0f) > 7) + ul += 0x10; + ul &= ~0x0f; + ul += 0x10; // fudge factor + + if (!LastPpi) + LastPpi = ul; + if (!FreqPpi) + FreqPpi = LastPpi; + + /* + * New Average Ppi is derived from previous AveragePpi, + * plus last Ppi sample count plus current Ppi sample + * count to get a frequency which has minimal variation + * and at the same time responsive to change in the + * apps pulse rate. + */ + FreqPpi = ((FreqPpi << 2) + LastPpi + ul)/6; + if ((FreqPpi & 0x0f) > 7) + FreqPpi += 0x10; + FreqPpi &= ~0x0f; + + LastPpi = ul; + PpiCycles = 0; + +} + + + +/*============================================================ + +Function: PlayContinuousTone() +Called by: The SoftPC timer. + +==============================================================*/ + +void PlayContinuousTone(void) +{ + ULONG Elapsed; + + host_ica_lock(); + + if (PpiCounting) { + Elapsed = GetTickCount(); + Elapsed = Elapsed > ET2TicCount ? Elapsed - ET2TicCount + : 0xFFFFFFFF - ET2TicCount + Elapsed; + if (Elapsed > 200) { + PpiCounting = 0; + LastPpi = 0; + FreqPpi = 0; + } + } + + PlaySound(FALSE); + + if (!BeepLastFreq && !BeepLastDuration && + BeepCloseCount && !--BeepCloseCount) + { + if (hBeepDevice && hBeepDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hBeepDevice); + hBeepDevice = 0; + } + } + + host_ica_unlock(); +} |