Skip to content

Commit 9aef149

Browse files
committed
C# version of the library which will now be the supported project.
1 parent 32325f8 commit 9aef149

File tree

9 files changed

+978
-8
lines changed

9 files changed

+978
-8
lines changed

BasicAudio.VisualBasic/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
3131
' by using the '*' as shown below:
3232
' <Assembly: AssemblyVersion("1.0.*")>
3333

34-
<Assembly: AssemblyVersion("1.3.0.0")>
35-
<Assembly: AssemblyFileVersion("1.3.0.0")>
34+
<Assembly: AssemblyVersion("1.4.0.0")>
35+
<Assembly: AssemblyFileVersion("1.4.0.0")>

BasicAudio.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1212
EndProject
1313
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "BasicAudio.VisualBasic", "BasicAudio.VisualBasic\BasicAudio.VisualBasic.vbproj", "{5BDF22B9-DF92-4F0B-83E2-E527A6B74FD6}"
1414
EndProject
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicAudio", "BasicAudio\BasicAudio.csproj", "{B154FC05-4592-4CAC-BDFD-D76E5770432B}"
16+
EndProject
1517
Global
1618
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1719
Debug|Any CPU = Debug|Any CPU
@@ -26,6 +28,10 @@ Global
2628
{5BDF22B9-DF92-4F0B-83E2-E527A6B74FD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
2729
{5BDF22B9-DF92-4F0B-83E2-E527A6B74FD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
2830
{5BDF22B9-DF92-4F0B-83E2-E527A6B74FD6}.Release|Any CPU.Build.0 = Release|Any CPU
31+
{B154FC05-4592-4CAC-BDFD-D76E5770432B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32+
{B154FC05-4592-4CAC-BDFD-D76E5770432B}.Debug|Any CPU.Build.0 = Debug|Any CPU
33+
{B154FC05-4592-4CAC-BDFD-D76E5770432B}.Release|Any CPU.ActiveCfg = Release|Any CPU
34+
{B154FC05-4592-4CAC-BDFD-D76E5770432B}.Release|Any CPU.Build.0 = Release|Any CPU
2935
EndGlobalSection
3036
GlobalSection(SolutionProperties) = preSolution
3137
HideSolutionNode = FALSE

BasicAudio/AudioPlayer.cs

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.IO;
4+
using BasicAudio.Extensions;
5+
using System.Text;
6+
7+
namespace BasicAudio
8+
{
9+
10+
/// <summary>
11+
/// This class is a wrapper for the Windows API calls to play wave, midi or mp3 files. Although this is .Net Standard 2 compliant
12+
/// it requires PInvokes to the Windows API and will fail in environments like Linux, Windows Universal Apps, Server environments, etc.
13+
/// </summary>
14+
/// <remarks>
15+
/// This class was originally designed for use in traditional Windows apps long before the invent of .Net Standard. It is highly
16+
/// recommended to use a library like NAudio for advanced audio capability.
17+
/// </remarks>
18+
public class AudioPlayer
19+
{
20+
//*********************************************************************************************************************
21+
//
22+
// Class: AudioPlayer
23+
// Organization: http://www.blakepell.com
24+
// Initial Date: 03/31/2007
25+
// Last Updated: 04/05/2019
26+
// Programmer(s): Blake Pell, blakepell@hotmail.com
27+
//
28+
//*********************************************************************************************************************
29+
30+
[DllImport("winmm.dll")]
31+
static extern int mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);
32+
33+
/// <summary>
34+
/// Constructor
35+
/// </summary>
36+
public AudioPlayer()
37+
{
38+
39+
}
40+
41+
/// <summary>
42+
/// Constructor: Location is the filename of the media to play. Wave files, mp3 files and midi files are the supported formats.
43+
/// </summary>
44+
/// <param name="filePath">File path of the media to play.</param>
45+
public AudioPlayer(string filePath)
46+
{
47+
this.Filename = filePath;
48+
}
49+
50+
/// <summary>
51+
/// Plays the file that is specified as the filename.
52+
/// </summary>
53+
public void Play()
54+
{
55+
// Some basic checks to make sure a file exists and is available, if not throw an exception the caller
56+
// can then handle.
57+
if (string.IsNullOrEmpty(Filename))
58+
{
59+
throw new FileNotFoundException("No file was provided to Play.");
60+
}
61+
62+
if (!File.Exists(this.Filename))
63+
{
64+
throw new FileNotFoundException("File does not exist or is inaccessible.");
65+
}
66+
67+
// There is probably a better way to do this than to go off of the extension but this is what
68+
// we're going to do for now unless someone has a need to better identify the file type.
69+
switch (Filename.SafeRight(3).ToLower())
70+
{
71+
case "mp3":
72+
mciSendString($"open \"{Filename}\" type mpegvideo alias audiofile", null, 0, IntPtr.Zero);
73+
74+
string playCommand = "play audiofile from 0";
75+
76+
if (Wait == true)
77+
{
78+
playCommand += " wait";
79+
}
80+
81+
mciSendString(playCommand, null, 0, IntPtr.Zero);
82+
break;
83+
case "wav":
84+
mciSendString($"open \"{Filename}\" type waveaudio alias audiofile", null, 0, IntPtr.Zero);
85+
mciSendString("play audiofile from 0", null, 0, IntPtr.Zero);
86+
break;
87+
case "mid":
88+
case "idi":
89+
var sb = new StringBuilder(128);
90+
91+
mciSendString("stop midi", sb, 0, IntPtr.Zero);
92+
mciSendString("close midi", sb, 0, IntPtr.Zero);
93+
mciSendString($"open sequencer!{Filename} alias midi", sb, 0, IntPtr.Zero);
94+
mciSendString("play midi", sb, 0, IntPtr.Zero);
95+
break;
96+
default:
97+
Close();
98+
throw new Exception("File type not supported.");
99+
}
100+
101+
IsPaused = false;
102+
103+
}
104+
105+
/// <summary>
106+
/// Pause the current play back.
107+
/// </summary>
108+
public void Pause()
109+
{
110+
mciSendString("pause audiofile", null, 0, IntPtr.Zero);
111+
IsPaused = true;
112+
}
113+
114+
/// <summary>
115+
/// Resume the current play back if it is currently paused.
116+
/// </summary>
117+
public void Resume()
118+
{
119+
mciSendString("resume audiofile", null, 0, IntPtr.Zero);
120+
IsPaused = false;
121+
}
122+
123+
/// <summary>
124+
/// Stop the current file if it's playing.
125+
/// </summary>
126+
public void Stop()
127+
{
128+
mciSendString("stop audiofile", null, 0, IntPtr.Zero);
129+
}
130+
131+
/// <summary>
132+
/// Close the file.
133+
/// </summary>
134+
public void Close()
135+
{
136+
mciSendString("close audiofile", null, 0, IntPtr.Zero);
137+
}
138+
139+
/// <summary>
140+
/// Halt the program until the .wav file is done playing. Be careful, this will lock the entire program up until the
141+
/// file is done playing. It behaves as if the Windows Sleep API is called while the file is playing (and maybe it is, I don't
142+
/// actually know, I'm just theorizing). :P
143+
/// </summary>
144+
public bool Wait { get; set; } = false;
145+
146+
/// <summary>
147+
/// Sets the audio file's time format via the mciSendString API.
148+
/// </summary>
149+
/// <value></value>
150+
public int Milleseconds
151+
{
152+
get
153+
{
154+
var sb = new StringBuilder(255);
155+
mciSendString("set audiofile time format milliseconds", null, 0, IntPtr.Zero);
156+
mciSendString("status audiofile length", sb, 255, IntPtr.Zero);
157+
158+
// Get rid of the nulls
159+
sb.Replace("\0", "");
160+
161+
// Get rid of the nulls, they muck things up
162+
if (string.IsNullOrEmpty(sb.ToString()))
163+
{
164+
return 0;
165+
}
166+
else
167+
{
168+
return Convert.ToInt32(sb.ToString());
169+
}
170+
}
171+
}
172+
173+
/// <summary>
174+
/// Gets the status of the current playback file via the mciSendString API.
175+
/// </summary>
176+
public string Status
177+
{
178+
get
179+
{
180+
var sb = new StringBuilder();
181+
mciSendString("status audiofile mode", sb, 255, IntPtr.Zero);
182+
183+
// Get rid of the nulls
184+
sb.Replace("\0", "");
185+
186+
return sb.ToString();
187+
}
188+
}
189+
190+
/// <summary>
191+
/// Gets the file size of the current audio file.
192+
/// </summary>
193+
public long FileSize
194+
{
195+
get
196+
{
197+
try
198+
{
199+
return new FileInfo(Filename).Length;
200+
}
201+
catch
202+
{
203+
return -1;
204+
}
205+
}
206+
}
207+
208+
/// <summary>
209+
/// Gets the channels of the file via the mciSendString API.
210+
/// </summary>
211+
public int Channels
212+
{
213+
get
214+
{
215+
var sb = new StringBuilder(255);
216+
mciSendString("status audiofile channels", sb, 255, IntPtr.Zero);
217+
218+
if (sb.ToString().IsNumeric())
219+
{
220+
return Convert.ToInt32(sb.ToString());
221+
}
222+
else
223+
{
224+
return -1;
225+
}
226+
}
227+
}
228+
229+
/// <summary>
230+
/// Used for debugging purposes.
231+
/// </summary>
232+
public string Debug
233+
{
234+
get
235+
{
236+
var sb = new StringBuilder(255);
237+
mciSendString("status audiofile channels", sb, 255, IntPtr.Zero);
238+
239+
return sb.ToString();
240+
}
241+
}
242+
243+
/// <summary>
244+
/// Whether or not the current playback is paused.
245+
/// </summary>
246+
public bool IsPaused { get; set; } = false;
247+
248+
/// <summary>
249+
/// The current filename of the file that is to be played back.
250+
/// </summary>
251+
/// <value></value>
252+
public string Filename { get; set; }
253+
254+
}
255+
256+
}

BasicAudio/BasicAudio.csproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;netstandard1.6;netstandard1.5;netstandard1.4;netstandard1.3;net472;net471;net47;net462;net461;net46;net452;net451;net45;net4;net35</TargetFrameworks>
5+
<Version>2019.4.5.1</Version>
6+
<Authors>Blake Pell</Authors>
7+
<Company>http://www.blakepell.com</Company>
8+
<Description>Basic Audio Recording for Windows. Although .Net Standard compliant requires Windows API's for audio recording and playback.</Description>
9+
<Copyright>Copyright © 2007-2019</Copyright>
10+
<PackageProjectUrl>https://github.com/blakepell/BasicAudio</PackageProjectUrl>
11+
<RepositoryUrl>https://github.com/blakepell/BasicAudio</RepositoryUrl>
12+
<RepositoryType>git</RepositoryType>
13+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
14+
</PropertyGroup>
15+
16+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
17+
<DocumentationFile></DocumentationFile>
18+
</PropertyGroup>
19+
20+
</Project>

0 commit comments

Comments
 (0)