123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- 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.
|