Skip to content

Latest commit

 

History

History
3172 lines (2887 loc) · 111 KB

mikmod.texi

File metadata and controls

3172 lines (2887 loc) · 111 KB
 
Nov 10, 2019
Nov 10, 2019
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename mikmod.info
@settitle MikMod sound library
@c %**end of header
@ignore
MikMod Sound Library Documentation
@end ignore
@c comment this during modifications
@finalout
@c @iftex
@c @afourpaper
@c @end iftex
@syncodeindex tp vr
@set documentation-version 1.3
@set documentation-date August 2016
@set library-version 3.1.21
@set authorname Miodrag Vallat
@set authoraddress miod@@mikmod.org
@c ========================================================== Copyright (info)
@ifinfo
Copyright @copyright{} 1998-2014 Miodrag Vallat and others --- see
file AUTHORS for complete list.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@end ifinfo
@c ========================================================== Title page
@titlepage
@title MikMod Sound Library
@subtitle Documentation edition @value{documentation-version}
@subtitle @value{documentation-date}
@author @value{authorname}
@author (@code{@value{authoraddress}})
@page
@vskip 0pt plus 1filll
@c ========================================================== Copyright (TeX)
Copyright @copyright{} 1998-2014 Miodrag Vallat and others --- see
file AUTHORS for complete list.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@end titlepage
@c ========================================================== File information
@ifnottex
@dircategory Programming
@direntry
* MikMod: (mikmod). MikMod Sound Library.
@end direntry
@c ========================================================== Top node
@node Top, Introduction, (dir), (dir)
@top MikMod Sound Library
@w{This manual documents the MikMod Sound Library, version @value{library-version}.}
@menu
* Introduction:: What is MikMod ?
* Tutorial:: Your first steps with MikMod.
* Using the Library:: A thematic presentation of the library.
* Library Reference:: Detailed description of the functions and variables.
* Index::
@end menu
@end ifnottex
@c ========================================================== Introduction
@node Introduction, Tutorial, Top, Top
@chapter Introduction
The MikMod sound library is an excellent way for a programmer to add music
and sound effects to an application. It is a powerful and flexible library,
with a simple and easy-to-learn API.
Besides, the library is very portable and runs under a lot of Unices, as well
as under OS/2, MacOS and Windows. Third party individuals also maintain ports
on other systems, including MS-DOS, and BeOS.
MikMod is able to play a wide range of module formats, as well as digital sound
files. It can take advantage of particular features of your system, such as
sound redirection over the network. And due to its modular nature, the library
can be extended to support more sound or module formats, as well as new
hardware or other sound output capabilities, as they appear.
@c ========================================================== Tutorial
@node Tutorial, Using the Library, Introduction, Top
@chapter Tutorial
This chapter will describe how to quickly incorporate MikMod's power into
your programs. It doesn't cover everything, but that's a start and I hope
it will help you understand the library philosophy.
If you have a real tutorial to put here, you're welcome ! Please send it to
me@enddots{}
@menu
* MikMod Concepts:: A few things you'll need to know.
* A Skeleton Program:: The shortest MikMod program.
* Playing Modules:: How to create a simple module player.
* Playing Sound Effects:: How to play simple sound effects.
* More Sound Effects:: How to play more complex sound effects.
@end menu
@c ========================================================== Concepts
@node MikMod Concepts, A Skeleton Program, Tutorial, Tutorial
@section MikMod Concepts
MikMod's sound output is composed of several sound @emph{voices} which are
mixed, either in software or in hardware, depending of your hardware
configuration. Simple sounds, like sound effects, use only one voice, whereas
sound modules, which are complex arrangements of sound effects, use several
voices.
MikMod's functions operate either globally, or at the voice level. Differences
in the handling of sound effects and modules are kept minimal, at least for
the programmer.
The sound playback is done by a @emph{sound driver}. MikMod provides several
sound drivers: different hardware drivers, and some software drivers to
redirect sound in a file, or over the network. You can even add your own
driver, register it to make it known by the library, and select it (this is
exactly what the module plugin of xmms does).
@c ========================================================== Skeleton
@node A Skeleton Program, Playing Modules, MikMod Concepts, Tutorial
@section A Skeleton Program
@iftex
@findex MikMod_Exit
@findex MikMod_Init
@findex MikMod_RegisterAllDrivers
@end iftex
To use MikMod in your program, there are a few steps required:
@itemize @bullet
@item Include @file{mikmod.h} in your program.
@item Register the MikMod drivers you need.
@item Initialize the library with MikMod_Init() before using any other MikMod
function.
@item Give up resources with MikMod_Exit() at the end of your program, or before
when MikMod is not needed anymore.
@item Link your application with the MikMod sound library.
@end itemize
Here's a program which meets all those conditions:
@example
/* MikMod Sound Library example program: a skeleton */
#include <mikmod.h>
main()
@{
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* initialize the library */
MikMod_Init("");
/* we could play some sound here... */
/* give up */
MikMod_Exit();
@}
@end example
This program would be compiled with the following command line:
@code{cc -o example example.c `libmikmod-config --cflags` `libmikmod-config --libs`}
Although this programs produces no useful result, many things happen when you
run it. The call to @code{MikMod_RegisterAllDrivers} registers all the drivers
embedded in the MikMod library. Then, @code{MikMod_Init} chooses the more
adequate driver and initializes it. The program is now ready to produce sound.
When sound is not needed any more, @code{MikMod_Exit} is used to relinquish
memory and let other programs have access to the sound hardware.
@c ========================================================== Modules
@node Playing Modules, Playing Sound Effects, A Skeleton Program, Tutorial
@section Playing Modules
@iftex
@findex MikMod_Exit
@findex MikMod_Init
@findex MikMod_RegisterAllDrivers
@findex MikMod_RegisterAllLoaders
@findex MikMod_Update
@vindex MikMod_errno
@findex MikMod_strerror
@findex Player_Active
@findex Player_Free
@findex Player_Load
@findex Player_Start
@findex Player_Stop
@end iftex
Our program is not really useful if it doesn't produce sound. Let's suppose
you've got this good old module, ``Beyond music'', in the file
@file{beyond music.mod}. How about playing it ?
To do this, we'll use the following code:
@example
/* MikMod Sound Library example program: a simple module player */
#include <unistd.h>
#include <mikmod.h>
main()
@{
MODULE *module;
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* register all the module loaders */
MikMod_RegisterAllLoaders();
/* initialize the library */
md_mode |= DMODE_SOFT_MUSIC;
if (MikMod_Init("")) @{
fprintf(stderr, "Could not initialize sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
@}
/* load module */
module = Player_Load("beyond music.mod", 64, 0);
if (module) @{
/* start module */
Player_Start(module);
while (Player_Active()) @{
/* we're playing */
usleep(10000);
MikMod_Update();
@}
Player_Stop();
Player_Free(module);
@} else
fprintf(stderr, "Could not load module, reason: %s\n",
MikMod_strerror(MikMod_errno));
/* give up */
MikMod_Exit();
@}
@end example
What's new here ? First, we've not only registered MikMod's device driver,
but also the module loaders. MikMod comes with a large choice of module
loaders, each one for a different module type. Since @emph{every} loader is
called to determine the type of the module when we try to load them, you may
want to register only a few of them to save time. In our case, we don't matter,
so we happily register every module loader.
Then, there's an extra line before calling @code{MikMod_Init}. We change the
value of MikMod's variable @code{md_mode} to tell the library that we want the
module to be processed by the software. If you're the happy owner of a GUS-type
card, you could use the specific hardware driver for this card, but in this
case you should not set the @code{DMODE_SOFT_MUSIC} flag.
We'll ensure that @code{MikMod_Init} was successful. Note that, in case of
error, MikMod provides the variable @code{MikMod_errno}, an equivalent of
the C library @code{errno} for MikMod errors, and the function
@code{MikMod_strerror}, an equivalent to @code{strerror}.
Now onto serious business ! The module is loaded with the @code{Player_Load}
function, which takes the name of the module file, and the number of voices
afforded to the module. In this case, the module has only 4 channels, so 4
voices, but complex Impulse Tracker modules can have a lot of voices (as they
can have as many as 256 virtual channels with so-called ``new note actions'').
Since empty voices don't cost time to be processed, it is safe to use a big
value, such as 64 or 128. The third parameter is the ``curiosity'' of the
loader: if nonzero, the loader will search for hidden parts in the module.
However, only a few module formats can embed hidden or non played parts, so
we'll use 0 here.
Now that the module is ready to play, let's play it. We inform the player that
the current module is @code{module} with @code{Player_Start}. Playback starts,
but we have to update it on a regular basis. So there's a loop on the result
of the @code{Player_Active} function, which will tell us if the module has
finished. To update the sound, we simply call @code{MikMod_Update}.
After the module has finished, we tell the player its job is done with
@code{Player_Stop}, and we free the module with @code{Player_Free}.
@c ========================================================== Sound effects
@node Playing Sound Effects, More Sound Effects, Playing Modules, Tutorial
@section Playing Sound Effects
@iftex
@findex MikMod_DisableOutput
@findex MikMod_EnableOutput
@findex MikMod_Exit
@findex MikMod_Init
@findex MikMod_RegisterAllDrivers
@findex MikMod_SetNumVoices
@findex MikMod_Update
@findex Voice_Stopped
@findex Sample_Free
@findex Sample_Load
@findex Sample_Play
@end iftex
MikMod is not limited to playing modules, it can also play sound effects, that
is, module samples. It's a bit more complex than playing a module, because the
module player does a lot of things for us, but here we'll get more control over
what is actually played by the program. Let's look at an example:
@example
/* MikMod Sound Library example program: sound effects */
#include <unistd.h>
#include <mikmod.h>
main()
@{
int i;
/* sound effects */
SAMPLE *sfx1, *sfx2;
/* voices */
int v1, v2;
/* register all the drivers */
MikMod_RegisterAllDrivers();
/* initialize the library */
md_mode |= DMODE_SOFT_SNDFX;
if (MikMod_Init("")) @{
fprintf(stderr, "Could not initialize sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
@}
/* load samples */
sfx1 = Sample_Load("first.wav");
if (!sfx1) @{
MikMod_Exit();
fprintf(stderr, "Could not load the first sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
@}
sfx2 = Sample_Load("second.wav");
if (!sfx2) @{
Sample_Free(sfx1);
MikMod_Exit();
fprintf(stderr, "Could not load the second sound, reason: %s\n",
MikMod_strerror(MikMod_errno));
return;
@}
/* reserve 2 voices for sound effects */
MikMod_SetNumVoices(-1, 2);
/* get ready to play */
MikMod_EnableOutput();
/* play first sample */
v1 = Sample_Play(sfx1, 0, 0);
for(i = 0; i < 5; i++) @{
MikMod_Update();
usleep(100000);
@}
/* half a second later, play second sample */
v2 = Sample_Play(sfx2, 0, 0);
do @{
MikMod_Update();
usleep(100000);
@} while (!Voice_Stopped(v2));
MikMod_DisableOutput();
Sample_Free(sfx2);
Sample_Free(sfx1);
MikMod_Exit();
@}
@end example
As in the previous example, we begin by registering the sound drivers and
initializing the library. We also ask for software mixing by modifying the
variable @code{md_mode}.
It's time to load our files, with the @code{Sample_Load} function. Don't forget
to test the return value --- it looks ugly here on such a small example, but
it's a good practice@enddots{}
Since we want to play two samples, we have to use at least two voices for this,
so we reserve them with a @code{MikMod_SetNumVoices} call. The first parameter
sets the number of module voices, and the second parameter the number of sound
effect voices. We don't want to set the number of module voices here (it's part
of the module player's duty), so we use the value @code{-1} to keep the current
value, and we reserve two sound effect voices.
Now we're ready to play, so we call @code{MikMod_EnableOutput} to make the
driver ready. Sound effects are played by the @code{Sample_Play} function.
You just have to specify which sample you want to play, the offset from which
you want to start, and the playback flags. More on this later. The function
returns the number of the voice associated to the sample.
We play the first sample for half a second, then we start to play the second
sample. Since we've reserved two channels, both samples play simultaneously. We
use the @code{Voice_Stopped} function to stop the playback: it returns the
current status of the voice argument, which is zero when the sample plays and
nonzero when it has finished. So the @code{do} loop will stop exactly when
the second sample is finished, regardless of the length of the first sample.
To finish, we get rid of the samples with @code{Sample_Free}.
@c ========================================================== More effects
@node More Sound Effects, , Playing Sound Effects, Tutorial
@section More Sound Effects
@iftex
@findex MikMod_Update
@findex Sample_Play
@findex Voice_SetFrequency
@findex Voice_SetPanning
@findex Voice_SetVolume
@findex Voice_Stop
@findex Voice_Stopped
@end iftex
Sound effects have some attributes that can be affected to control the playback.
These are speed, panning, and volume. Given a voice number, you can affect these
attributes with the @code{Voice_SetFrequency}, @code{Voice_SetPanning} and
@code{Voice_SetVolume} functions.
In the previous example, we'll replace the actual sound code, located between
the calls to @code{MikMod_EnableOutput} and @code{MikMod_DisableOutput}, with
the following code:
@example
Sample_Play(sfx1, 0, 0);
for(i = 0; i < 5; i++) @{
MikMod_Update();
usleep(100000);
@}
v2 = Sample_Play(sfx2, 0, SFX_CRITICAL);
i = 0;
do @{
MikMod_Update();
usleep(100000);
v1 = Sample_Play(sfx1, 0, 0);
Voice_SetVolume(v1, 160);
Voice_SetFrequency(v1, (sfx1->speed * (100 + i)) / 100);
Voice_SetPanning(v2, (i++ & 1) ? PAN_LEFT : PAN_RIGHT);
@} while (!Voice_Stopped(v2));
@end example
The first thing you'll notice, is the @code{SFX_CRITICAL} flag used to play the
second sample. Since the @code{do} loop will add another sample every 100
@dmn{milliseconds}, and we reserved only two voices, the oldest voice will be
cut each time this is necessary. Doing this would cut the second sample in the
second iteration of the loop. However, since we flagged this sound as
``critical'', it won't be cut until it is finished or we stop it with a
@code{Voice_Stop} call. So the second sample will play fine, whereas the first
sample will be stopped every loop iteration.
Then, we choose to play the first sample a bit lower, with
@code{Voice_SetVolume}. Volume voices range from 0 (silence) to 256. In
this case we play the sample at 160. To make the sound look weird, we also
change its frequency with @code{Voice_SetFrequency}. The computation in the
example code makes the frequency more and more high (starting from the sample
frequency and then increasing from 1% each iteration).
And to demonstrate the @code{Voice_SetPanning} function, we change the panning
of the second sample at each iteration from the left to the right. The argument
can be one of the standard panning @code{PAN_LEFT}, @code{PAN_RIGHT},
@code{PAN_CENTER} and @code{PAN_SURROUND}@footnote{@code{PAN_SURROUND} will be
mapped to @code{PAN_CENTER} if the library is initialized without surround
sound, that is, if the variable @code{md_mode} doesn't have the bit
@code{DMODE_SURROUND} set.}, or a numeric value between 0 (@code{PAN_LEFT}) and
255 (@code{PAN_RIGHT}).
@c ========================================================== Using
@node Using the Library, Library Reference, Tutorial, Top
@chapter Using the Library
This chapter describes the various parts of the library and their uses.
@menu
* Library Version::
* Type Definitions::
* Error Handling::
* Library Initialization::
* Samples and Voice Control::
* Modules and Player Control::
* Loading Data from Memory::
@end menu
@c ========================================================== Version
@node Library Version, Type Definitions, Using the Library, Using the Library
@section Library Version
@iftex
@findex MikMod_GetVersion
@end iftex
If your program is dynamically linked with the MikMod library, you should check
which version of the library you're working with.
To do this, the library defines a few constants and a function to help you
determine if the current library is adequate for your needs or if it has to
be upgraded.
When your program includes @code{mikmod.h}, the following constants are
defined:
@itemize @bullet
@item @code{LIBMIKMOD_VERSION_MAJOR} is equal to the major version number of
the library.
@item @code{LIBMIKMOD_VERSION_MINOR} is equal to the minor version number of
the library.
@item @code{LIBMIKMOD_REVISION} is equal to the revision number of the library.
@item @code{LIBMIKMOD_VERSION} is the sum of @code{LIBMIKMOD_VERSION_MAJOR} shifted 16 times, @code{LIBMIKMOD_VERSION_MINOR} shifted 8 times, and
@code{LIBMIKMOD_REVISION}.
@end itemize
So your program can tell with which version of the library it has been compiled
this way:
@example
printf("Compiled with MikMod Sound Library version %ld.%ld.%ld\n",
LIBMIKMOD_VERSION_MAJOR,
LIBMIKMOD_VERSION_MINOR,
LIBMIKMOD_REVISION);
@end example
The library defines the function @code{MikMod_GetVersion} which returns the
value of LIBMIKMOD_VERSION for the library. If this value is greater than or
equal to the value of LIBMIKMOD_VERSION for your program, your program will
work; otherwise, you'll have to inform the user that he has to upgrade the
library:
@example
@{
long engineversion = MikMod_GetVersion();
if (engineversion < LIBMIKMOD_VERSION) @{
printf("MikMod library version (%ld.%ld.%ld) is too old.\n",
(engineversion >> 16) & 255,
(engineversion >> 8) & 255,
(engineversion) & 255);
printf("This programs requires at least version %ld.%ld.%ld\n",
LIBMIKMOD_VERSION_MAJOR,
LIBMIKMOD_VERSION_MINOR,
LIBMIKMOD_REVISION);
puts("Please upgrade your MikMod library.");
exit(1);
@}
@}
@end example
@c ========================================================== Types
@node Type Definitions, Error Handling, Library Version, Using the Library
@section Type Definitions
@iftex
@tindex BOOL
@tindex CHAR
@tindex SBYTE
@tindex SLONG
@tindex SWORD
@tindex UBYTE
@tindex ULONG
@tindex UWORD
@end iftex
MikMod defines several data types to deal with modules and sample data.
These types have the same memory size on every platform MikMod has been ported
to.
These types are:
@itemize @bullet
@item @code{CHAR} is a printable character. For now it is the same as the
@code{char} type, but in the future it may be wide char (Unicode) on some
platforms.
@item @code{SBYTE} is a signed 8 bit number (can range from -128 to 127).
@item @code{UBYTE} is an unsigned 8 bit number (can range from 0 to 255).
@item @code{SWORD} is a signed 16 bit number (can range from -32768 to 32767).
@item @code{UWORD} is an unsigned 16 bit number (can range from 0 to 65535).
@item @code{SLONG} is a signed 32 bit number (can range from -2.147.483.648 to
2.147.483.647).
@item @code{ULONG} is an unsigned 32 bit number (can range from 0 to
4.294.967.296).
@item @code{BOOL} is a boolean value. A value of 0 means false, any other value
means true.
@end itemize
@c ========================================================== Errors
@node Error Handling, Library Initialization, Type Definitions, Using the Library
@section Error Handling
@iftex
@findex MikMod_RegisterErrorHandler
@vindex MikMod_critical
@vindex MikMod_errno
@vindex MikMod_strerror
@end iftex
Although MikMod does its best to do its work, there are times where it can't.
For example, if you're trying to play a corrupted file, well, it can't.
A lot of MikMod functions return pointers or @code{BOOL} values. If the pointer
is @code{NULL} or the @code{BOOL} is 0 (false), an error has occurred.
MikMod errors are returned in the variable @code{MikMod_errno}. Each possible
error has a symbolic error code, beginning with @code{MMERR_}. For example, if
MikMod can't open a file, @code{MikMod_errno} will receive the value
@code{MMERR_OPENING_FILE}.
You can get an appropriate error message to display from the function
@code{MikMod_strerror}.
There is a second error variable named @code{MikMod_critical}. As its name
suggests, it is only set if the error lets the library in an unstable state.
This variable can only be set by the functions @code{MikMod_Init},
@code{MikMod_SetNumVoices} and @code{MikMod_EnableOutput}. If one of these
functions return an error and @code{MikMod_critical} is set, the library is left
in the uninitialized state (i.e. it was not initialized, or @code{MikMod_Exit}
was called).
If you prefer, you can use a callback function to get notified of errors. This
function must be prototyped as @code{void MyFunction(void)}. Then, call
@code{MikMod_RegisterHandler} with your function as argument to have it notified
when an error occurs. There can only be one callback function registered, but
@code{MikMod_RegisterHandler} will return you the previous handler, so you can
chain handlers if you want to.
@c ========================================================== Initialization
@node Library Initialization, Samples and Voice Control, Error Handling, Using the Library
@section Library Initialization and Core Functions
@iftex
@findex MikMod_Active
@findex MikMod_DisableOutput
@findex MikMod_EnableOutput
@findex MikMod_Exit
@findex MikMod_InfoDriver
@findex MikMod_Init
@findex MikMod_InitThreads
@findex MikMod_Lock
@findex MikMod_RegisterAllDrivers
@findex MikMod_RegisterDriver
@findex MikMod_Reset
@findex MikMod_SetNumVoices
@findex MikMod_Unlock
@findex MikMod_Update
@vindex md_device
@vindex md_mixfreq
@vindex md_mode
@end iftex
To initialize the library, you must register some sound drivers first. You can
either register all the drivers embedded in the library for your platform with
@code{MikMod_RegisterAllDrivers}, or register only some of them with
@code{MikMod_RegisterDriver}. If you choose to register the drivers manually,
you must be careful in their order, since @code{MikMod_Init} will try them in
the order you registered them. The @code{MikMod_RegisterAllDrivers} function
registers the network drivers first (for playing sound over the network), then
the hardware drivers, then the disk writers, and in last resort, the nosound
driver. Registering the nosound driver first would not be a very good
idea@enddots{}
You can get some printable information regarding the registered drivers with
@code{MikMod_InfoDriver}; don't forget to call @code{free} on the returned
string when you don't need it anymore.
After you've registered your drivers, you can initialize the sound playback
with @code{MikMod_Init}, passing specific information to the driver if
necessary. If you set the variable @code{md_device} to zero, which
is its default value, the driver will be autodetected, that is, the first driver
in the list that is available on the system will be used; otherwise only
the driver whose order in the list of the registered drivers is equal to
@code{md_device} will be tried. If your playback settings, in the variables
@code{md_mixfreq} and @code{md_mode}, are not supported by the device,
@code{MikMod_Init} will fail.
You can then choose the number of voices you need with
@code{MikMod_SetNumVoices}, and activate the playback with
@code{MikMod_EnableOutput}.
Don't forget to call @code{MikMod_Update} as often as possible to process the
sound mixing. If necessary, fork a dedicated process to do this, or if the
library is thread-safe on your system, use a dedicated thread.
If you want to change playback settings, most of them can't be changed on the
fly. You'll need to stop the playback and reinitialize the driver. Use
@code{MikMod_Active} to check if there is still sound playing; in this case,
call @code{MikMod_DisableOutput} to end playback. Then, change your settings
and call @code{MikMod_Reset}. You're now ready to select your number of voices
and restart playback.
When your program ends, don't forget to stop playback and call
@code{MikMod_Exit} to leave the sound hardware in a coherent state.
On systems that have pthreads, libmikmod is thread-safe@footnote{Unless you
explicitely choose to create a non thread-safe version of libmikmod at
compile-time.}. You can check this in your programs with the
@code{MikMod_InitThreads} function. If this function returns 1, the library is
thread-safe.
The main benefit of thread-safety is that @code{MikMod_Update} can be called
from a separate thread, which often makes application design easier. However,
several libmikmod global variables are accessible from all your threads, so
when more than one thread need to access libmikmod variables, you'll have to
protect these access with the @code{MikMod_Lock} and @code{MikMod_Unlock}
functions. If libmikmod is not thread-safe, these functions are no-ops.
@c ========================================================== Samples
@node Samples and Voice Control, Modules and Player Control, Library Initialization, Using the Library
@section Samples and Voice Control
@iftex
@findex Voice_GetFrequency
@findex Voice_GetPanning
@findex Voice_GetPosition
@findex Voice_GetVolume
@findex Voice_Play
@findex Voice_Stop
@findex Voice_Stopped
@findex Voice_SetFrequency
@findex Voice_SetPanning
@findex Voice_SetVolume
@findex Sample_Free
@findex Sample_Load
@findex Sample_LoadFP
@findex Sample_Play
@end iftex
Currently, MikMod only supports uncompressed mono WAV files as samples. You can
load a sample by calling @code{Sample_Load} with a filename, or by calling
@code{Sample_LoadFP} with an open @code{FILE*} pointer. These functions return
a pointer to a @code{SAMPLE} structure, or @code{NULL} in case of error.
The @code{SAMPLE} structure has a few interesting fields:
@itemize @minus
@item @code{speed} contains the default frequency of the sample.
@item @code{volume} contains the default volume of the sample, ranging from 0 (silence)
to 64.
@item @code{panning} contains the default panning position of the sample.
@end itemize
Altering one of those fields will affect all voices currently playing the
sample. You can achieve the same result on a single voice with the functions
@code{Voice_SetFrequency}, @code{Voice_SetVolume} and @code{Voice_SetPanning}.
Since the same sample can be played with different frequency, volume and panning
parameters on each voice, you can get voice specific information with
@code{Voice_GetFrequency}, @code{Voice_GetVolume} and @code{Voice_GetPanning}.
You can also make your sample loop by setting the fields @code{loopstart} and
@code{loopend} and or'ing @code{flags} with @code{SF_LOOP}. To compute your loop
values, the field @code{length} will be useful. However, you must know that
all the sample length are expressed in samples, i.e. 8 bits for an 8 bit sample,
and 16 bit for a 16 bit sample@dots{} Test @code{flags} for the value
@code{SF_16BITS} to know this.
Speaking of flags, if you're curious and want to know the original format of the
sample on disk (since libmikmod does some work on the sample data internally),
refer to the @code{inflags} field.
If the common forward loop isn't enough, you can play with some other flags:
@code{SF_BIDI} will make your sample loop ``ping pong'' (back and forth), and
@code{SF_REVERSE} will make it play backwards.
To play your sample, use the @code{Sample_Play} function. This function
will return a voice number which enable you to use the @code{Voice_xx}
functions.
The sample will play until another sample takes over its voice (when you play
more samples than you reserved sound effect voices), unless it has been flagged
as @code{SFX_CRITICAL}. You can force it to stop with @code{Voice_Stop}, or you
can force another sample to take over this voice with @code{Voice_Play};
however @code{Voice_Play} doesn't let you flag the new sample as critical.
Non looping samples will free their voice channel as soon as they are finished;
you can know the current playback position of your sample with
@code{Voice_GetPosition}. If it is zero, either the sample has finished playing
or it is just beginning; use @code{Voice_Stopped} to know.
When you don't need a sample anymore, don't forget to free its memory with
@code{Sample_Free}.
@c ========================================================== Module player
@node Modules and Player Control, Loading Data from Memory, Samples and Voice Control, Using the Library
@section Modules and Player Control
@iftex
@findex MikMod_InfoLoader
@findex MikMod_RegisterAllLoaders
@findex MikMod_RegisterLoader
@findex MikMod_RegisterPlayer
@findex Player_Active
@findex Player_Free
@findex Player_GetChannelVoice
@findex Player_GetModule
@findex Player_Load
@findex Player_LoadFP
@findex Player_LoadTitle
@findex Player_LoadTitleFP
@findex Player_Mute
@findex Player_Muted
@findex Player_NextPosition
@findex Player_Paused
@findex Player_PrevPosition
@findex Player_SetPosition
@findex Player_SetSpeed
@findex Player_SetTempo
@findex Player_SetVolume
@findex Player_Start
@findex Player_Stop
@findex Player_ToggleMute
@findex Player_TogglePause
@findex Player_UnMute
@end iftex
As for the sound drivers, you have to register the module loaders you want to
use for MikMod to be able to load modules. You can either register all the
module loaders with @code{MikMod_RegisterAllLoaders}, or only a few of them with
@code{MikMod_RegisterLoader}. Be careful if you choose this solution, as the
15 instrument MOD loader has to be registered last, since loaders are called in
the order they were register to identify modules, and the detection of this
format is not fully reliable, so other modules might be mistaken as 15
instrument MOD files.
You can get some printable information regarding the registered loaders with
@code{MikMod_InfoLoader}; don't forget to call @code{free} on the returned
string when you don't need it anymore.
Note that, contrary to the sound drivers, you can register module loaders at
any time, it doesn't matter.
For playlists, you might be interested in knowing the module title first, and
@code{Player_LoadTitle} will give you this information. Don't forget to
@code{free} the returned text when you don't need it anymore.
You can load a module either with @code{Player_Load} and the name of the
module, or with @code{Player_LoadFP} and an open @code{FILE*} pointer. These
functions also expect a maximal number of voices, and a curiosity flag. Unless
you have excellent reasons not to do so, choose a big limit, such as 64 or even
128 for complex Impulse Tracker modules. Both functions return a pointer to an
@code{MODULE} structure, or @code{NULL} if an error occurs.
You'll find some useful information in this structure:
@itemize @minus
@item @code{numchn} contains the number of module ``real'' channels.
@item @code{numvoices} contains the number of voices reserved by the player for
the real channels and the virtual channels (NNA).
@item @code{numpas} and @code{numpat} contain the number of song positions and
song patterns.
@item @code{numins} and @code{numsmp} contain the number of instruments and
samples.
@item @code{songname} contains the song title.
@item @code{modtype} contains the name of the tracker used to create the song.
@item @code{comment} contains the song comment, if it has one.
@item @code{sngtime} contains the time elapsed in the module, in
@math{2^@minus{}10} @dmn{seconds} (not exactly a millisecond).
@item @code{sngspd} and @code{bpm} contain the song speed and tempo.
@item @code{realchn} contains the actual number of active channels.
@item @code{totalchn} contains the actual number of active virtual channels,
i.e. the sum of @code{realchn} and the number of NNA virtual channels.
@end itemize
Now that the module is loaded, you need to tell the module player that you want
to play this particular module with @code{Player_Start} (the player can only
play one module, but you can have several modules in memory). The playback
begins. Should you forget which module is playing, @code{Player_GetModule} will
return it to you.
You can change the current song position with the functions
@code{Player_NextPosition}, @code{Player_PrevPosition} and
@code{Player_SetPosition}, the speed with @code{Player_SetSpeed} and
@code{Player_SetTempo}, and the volume (ranging from 0 to 128) with
@code{Player_SetVolume}.
Playback can be paused or resumed with @code{Player_TogglePause}. Be sure to
check with @code{Player_Paused} that it isn't already in the state you want !
Fine player control is achieved by the functions @code{Player_Mute},
@code{Player_UnMute} and @code{Player_ToggleMute} which can silence or resume
a set of module channels. The function @code{Player_Muted} will return the
state of a given channel. And if you want even more control, you can get the
voice corresponding to a module channel with @code{Player_GetChannelVoice} and
act directly on the voice.
Modules play only once, but can loop indefinitely if they are designed to do so.
You can change this behavior with the @code{wrap} and @code{loop} of the
@code{MODULE} structure; the first one, if set, will make the module restart
when it's finished, and the second one, if set, will prevent the module from
jumping backwards.
You can test if the module is still playing with @code{Player_Active}, and you
can stop it at any time with @code{Player_Stop}. When the module isn't needed
anymore, get rid of it with @code{Player_Free}.
@c ========================================================== Mreaders
@node Loading Data from Memory, ,Modules and Player Control, Using the Library
@section Loading Data from Memory
@iftex
@tindex MREADER
@tindex MWRITER
@findex Player_LoadGeneric
@findex Sample_LoadGeneric
@end iftex
If you need to load modules or sound effects from other places than plain
files, you can use the @code{MREADER} and @code{MWRITER} objects to achieve
this.
The @code{MREADER} and @code{MWRITER} structures contain a list of function
pointers, which emulate the behaviour of a regular @code{FILE *} object. In
fact, all functions which take filenames or @code{FILE *} as arguments are only
wrappers to a real function which takes an @code{MREADER} or an @code{MWRITER}
argument.
So, if you need to load a module from memory, or for a multi-file archive, for
example, all you need is to build an adequate @code{MREADER} object, and use
@code{Player_LoadGeneric} instead of @code{Player_Load} or
@code{Player_LoadFP}. For samples, use @code{Sample_LoadGeneric} instead of
@code{Sample_Load} or @code{Sample_LoadFP}.
@c ========================================================== Reference
@node Library Reference, Index, Using the Library, Top
@chapter Library Reference
This chapter describes in more detail all the functions and variables provided
by the library. @xref{Type Definitions}, for the basic type reference.
@menu
* Variable Reference::
* Structure Reference::
* Error Reference::
* Function Reference::
* Loader Reference::
* Driver Reference::
@end menu
@c ========================================================== Variable reference
@node Variable Reference, Structure Reference, Library Reference, Library Reference
@section Variable Reference
@subsection Error Variables
The following variables are set by the library to return error information.
@table @code
@vindex MikMod_errno
@item int MikMod_errno
When an error occurs, this variable contains the error code.
@xref{Error Reference}, for more information.
@vindex MikMod_critical
@item BOOL MikMod_critical
When an error occurs, this variable informs of the severity of the error. Its
value has sense only if the value of @code{MikMod_errno} is different from zero.
If the value of @code{MikMod_critical} is zero, the error wasn't fatal and the
library is in a stable state. However, if it is nonzero, then the library can't
be used and has reseted itself to the uninitialized state. This often means
that the mixing parameters you choose were not supported by the driver, or that
it doesn't has enough voices for your needs if you called
@code{MikMod_SetNumVoices}.
@end table
@subsection Sound Settings
The following variables control the sound output parameters and their changes
take effect immediately.
@table @code
@vindex md_musicvolume
@item UBYTE md_musicvolume
Volume of the module. Allowed values range from
0 to 128. The default value is 128.
@vindex md_pansep
@item UBYTE md_pansep
Stereo channels separation. Allowed values range
from 0 (no separation, thus mono sound) to 128 (full channel separation). The
default value is 128.
@vindex md_reverb
@item UBYTE md_reverb
Amount of sound reverberation. Allowed values range
from 0 (no reverberation) to 15 (a rough estimate for chaos@dots{}). The
default value is 0.
@vindex md_sndfxvolume
@item UBYTE md_sndfxvolume