summaryrefslogtreecommitdiffstats
path: root/private/mvdm/softpc.new/host/src/nt_sound.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/mvdm/softpc.new/host/src/nt_sound.c420
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();
+}