Little audio player in D

Posted 2020-12-21

I did some small changes to simpleaudio.d to give more control over it, then copied in some other ports from ketmar to the lib for more fun.

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on

simpleaudio.d just got new controls for its play* family of functions. They now return a SampleController object that can pause and stop them. Can also report position in playback.

I'm not sure I'm quite happy with it yet, but it works so I'll probably commit it.

I also added a port of the nuked opl3 emulator to the repo for 90's style midi playback. Just because I like it.

Lastly, image.d had an image resize function buried beneath its file format support. I separated that out to imageresize.d.

In my version, the repo now has over 40 dub subpackages and over 80 modules. So that release will be coming soon.

Audio Player in D

Using those new controls in simpleaudio, it is fairly easy to make a little audio player in D.

A user told me the mp3 player doesn't work for tiny (like 1/10 of a second) samples. I'll look into that later, but so far every other file I've tried here seems to work adequately.

This little player will do the emulated midi thing (90's style nostalgic sounds!), mp3, ogg vorbis, and wav files. The terminal UI shows the current position in seconds, then space pauses and resumes and q will quit. Hopefully... but it Works for Me lol.

This will only work on Windows and Linux, since I never implemented other OSes in simpleaudio.

Also note this program is GPL because some of its dependencies are.

1 module sample.audioplayer;
2 
3 import arsd.simpleaudio;
4 import arsd.terminal;
5 
6 import std.algorithm;
7 
8 void main(string[] args) {
9         Terminal terminal = Terminal(ConsoleOutputMode.linear);
10 
11         if(args.length < 2) {
12                 terminal.writeln("Give a file on the command line.");
13                 return;
14         }
15 
16         SampleController sc;
17         auto a = AudioOutputThread(true);
18         if(args[1].endsWith(".ogg"))
19                 sc = a.playOgg(args[1]);
20         else if(args[1].endsWith(".wav"))
21                 sc = a.playWav(args[1]);
22         else if(args[1].endsWith(".mid"))
23                 sc = a.playEmulatedOpl3Midi(args[1]);
24         else if(args[1].endsWith(".mp3"))
25                 sc = a.playMp3(args[1]);
26         else {
27                 terminal.writeln("I don't know how to play that file.");
28                 return;
29         }
30 
31         auto rtti = RealTimeConsoleInput(&terminal, ConsoleInputFlags.raw);
32 
33         bool paused = false;
34 
35         while(!sc.finished()) {
36 		// input can include things other than keys...
37                 if(rtti.timedCheckForInput(100) && rtti.kbhit()) {
38                         switch(rtti.getch()) {
39                                 case ' ':
40                                         if(paused)
41                                                 sc.resume();
42                                         else
43                                                 sc.pause();
44                                         paused = !paused;
45                                 break;
46                                 case 'q':
47                                         sc.stop();
48                                 break;
49                                 default:
50                         }
51                 }
52 
53                 terminal.write("\r", sc.position());
54                 terminal.flush();
55         }
56 
57         terminal.writeln();
58 }

You will need the arsd master files from git to use this. If it doesn't work, let me know, I haven't tested it too much yet. My goal is just to do some simple sounds in my game but still it is cool if I can do more.