forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwinsound.cs
More file actions
143 lines (110 loc) · 6.19 KB
/
winsound.cs
File metadata and controls
143 lines (110 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
#if FEATURE_NATIVE
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;
[assembly: PythonModule("winsound", typeof(IronPython.Modules.PythonWinsoundModule), PlatformsAttribute.PlatformFamily.Windows)]
namespace IronPython.Modules {
[SupportedOSPlatform("windows")]
public static class PythonWinsoundModule {
public static readonly string __doc__ = @"PlaySound(sound, flags) - play a sound
SND_FILENAME - sound is a wav file name
SND_ALIAS - sound is a registry sound association name
SND_LOOP - Play the sound repeatedly; must also specify SND_ASYNC
SND_MEMORY - sound is a memory image of a wav file
SND_PURGE - stop all instances of the specified sound
SND_ASYNC - PlaySound returns immediately
SND_NODEFAULT - Do not play a default beep if the sound can not be found
SND_NOSTOP - Do not interrupt any sounds currently playing
SND_NOWAIT - Return immediately if the sound driver is busy
Beep(frequency, duration) - Make a beep through the PC speaker.";
public const int SND_SYNC = 0x0000; /* play synchronously (default) */
public const int SND_ASYNC = 0x0001; /* play asynchronously */
public const int SND_NODEFAULT = 0x0002; /* silence (!default) if sound not found */
public const int SND_MEMORY = 0x0004; /* pszSound points to a memory file */
public const int SND_LOOP = 0x0008; /* loop the sound until next sndPlaySound */
public const int SND_NOSTOP = 0x0010; /* don't stop any currently playing sound */
public const int SND_NOWAIT = 0x00002000; /* don't wait if the driver is busy */
public const int SND_ALIAS = 0x00010000; /* name is a registry alias */
public const int SND_ALIAS_ID = 0x00110000; /* alias is a predefined ID */
public const int SND_FILENAME = 0x00020000; /* name is file name */
public const int SND_RESOURCE = 0x00040004; /* name is resource name or atom */
public const int SND_PURGE = 0x0040; /* purge non-static events for task */
public const int SND_APPLICATION = 0x0080; /* look for application specific association */
public const int MB_OK = 0x00000000;
public const int MB_ICONASTERISK = 0x00000040;
public const int MB_ICONEXCLAMATION = 0x00000030;
public const int MB_ICONHAND = 0x00000010;
public const int MB_ICONQUESTION = 0x00000020;
#region Private Implementation Details
[DllImport("winmm.dll")]
private static extern bool PlaySound(string fileName, IntPtr hMod, int flags);
[DllImport("winmm.dll")]
private static extern bool PlaySound(byte[] bytes, IntPtr hMod, int flags);
[DllImport("winmm.dll")]
private static extern bool PlaySound(IntPtr input, IntPtr hMod, int flags);
[DllImport("kernel32.dll")]
private static extern bool Beep(int dwFreq, int dwDuration);
[DllImport("user32.dll")]
private static extern bool MessageBeep(int uType);
#endregion
#region Public API
[Documentation(@"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API
The sound argument can be a filename, data, or None.
For flag values, ored together, see module documentation.")]
public static void PlaySound(CodeContext/*!*/ context, string? sound, int flags) {
if (sound is null) {
if (!PlaySound(IntPtr.Zero, IntPtr.Zero, flags)) {
throw PythonOps.RuntimeError("Failed to play sound");
}
} else {
if (((flags & SND_ASYNC) == SND_ASYNC) && ((flags & SND_MEMORY) == SND_MEMORY)) throw PythonOps.RuntimeError("Cannot play asynchronously from memory");
if ((flags & SND_MEMORY) == SND_MEMORY) throw PythonOps.TypeError($"a bytes-like object is required, not '{PythonOps.GetPythonTypeName(sound)}'");
if (sound.IndexOf((char)0) != -1) throw PythonOps.ValueError("embedded null character");
if (!PlaySound(sound, IntPtr.Zero, flags)) {
throw PythonOps.RuntimeError("Failed to play sound");
}
}
}
[Documentation(@"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API
The sound argument can be a filename, data, or None.
For flag values, ored together, see module documentation.")]
public static void PlaySound(CodeContext/*!*/ context, [NotNone] IBufferProtocol sound, int flags) {
if (((flags & SND_ASYNC) == SND_ASYNC) && ((flags & SND_MEMORY) == SND_MEMORY)) throw PythonOps.RuntimeError("Cannot play asynchronously from memory");
if ((flags & SND_MEMORY) == 0) throw PythonOps.TypeError($"'{nameof(sound)}' must be str or None, not '{PythonOps.GetPythonTypeName(sound)}'");
using var buffer = sound.GetBuffer();
if (!PlaySound(buffer.ToArray(), IntPtr.Zero, flags)) {
throw PythonOps.RuntimeError("Failed to play sound");
}
}
[Documentation(@"Beep(frequency, duration) - a wrapper around the Windows Beep API
The frequency argument specifies frequency, in hertz, of the sound.
This parameter must be in the range 37 through 32,767.
The duration argument specifies the number of milliseconds.
")]
public static void Beep(CodeContext/*!*/ context, int freq, int dur) {
if (freq < 37 || freq > 32767) {
throw PythonOps.ValueError("frequency must be in 37 thru 32767");
}
bool ok = Beep(freq, dur);
if (!ok) {
throw PythonOps.RuntimeError("Failed to beep");
}
}
[Documentation("MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK.")]
public static void MessageBeep(CodeContext/*!*/ context, int x=MB_OK) {
MessageBeep(x);
}
#endregion
}
}
#endif