blob: f923e22d8b16fe81419d9e70cfd58ffbc4c02dd5 (
plain)
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
|
program Streaming;
{$mode objfpc}
uses
ctypes, nds9, maxmod9;
var
sine: cint; // sine position
lfo: cint; // LFO position
const
// waveform base frequency
sine_freq = 500;
// LFO frequency
lfo_freq = 3;
// LFO output shift amount
lfo_shift = 4;
// blue backdrop
bg_colour = 13 shl 10;
// red cpu usage
cpu_colour = 31;
function on_stream_request(aLength: mm_word; aDest: mm_addr; aFormat: mm_stream_formats): mm_word;
var
target: pcint16;
len: cint;
sample: cint;
begin
target := aDest;
//------------------------------------------------------------
// synthensize a sine wave with an LFO applied to the pitch
// the stereo data is interleaved
//------------------------------------------------------------
len := aLength;
while len <> 0 do
begin
sample := sinLerp(sine);
// output sample for left
target^ := sample;
inc(target);
// output inverted sample for right
target^ := -sample;
inc(target);
sine := sine + sine_freq + (sinLerp(lfo) shr lfo_shift);
lfo := (lfo + lfo_freq);
dec(len);
end;
result := aLength;
end;
var
sys: mm_ds_system;
mystream: mm_stream;
begin
//----------------------------------------------------------------
// print out some stuff
//----------------------------------------------------------------
consoleDemoInit();
iprintf( #10' Maxmod Streaming Example '#10);
//----------------------------------------------------------------
// initialize maxmod without any soundbank (unusual setup)
//----------------------------------------------------------------
sys.mod_count := 0;
sys.samp_count := 0;
sys.mem_bank := nil;
sys.fifo_channel := FIFO_MAXMOD;
mmInit( @sys );
//----------------------------------------------------------------
// open stream
//----------------------------------------------------------------
mystream.sampling_rate := 25000; // sampling rate = 25khz
mystream.buffer_length := 1200; // buffer length = 1200 samples
mystream.callback := @on_stream_request; // set callback function
mystream.format := MM_STREAM_16BIT_STEREO; // format = stereo 16-bit
mystream.timer := MM_TIMER0; // use hardware timer 0
mystream.manual := 1; // use manual filling
mmStreamOpen( @mystream );
//----------------------------------------------------------------
// when using 'automatic' filling, your callback will be triggered
// every time half of the wave buffer is processed.
//
// so:
// 25000 (rate)
// ----- = ~21 Hz for a full pass, and ~42hz for half pass
// 1200 (length)
//----------------------------------------------------------------
// with 'manual' filling, you must call mmStreamUpdate
// periodically (and often enough to avoid buffer underruns)
//----------------------------------------------------------------
SetYtrigger( 0 );
irqEnable( IRQ_VCOUNT );
while true do
begin
// wait until line 0
swiIntrWait( 0, IRQ_VCOUNT);
// update stream
mmStreamUpdate();
// restore backdrop (some lines were drawn with another colour to show cpu usage)
BG_PALETTE_SUB[0] := bg_colour;
// wait until next frame
swiWaitForVBlank();
// set backdrop to show cpu usage
BG_PALETTE_SUB[0] := cpu_colour;
end;
end.
|