streaming.pp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. program Streaming;
  2. {$mode objfpc}
  3. uses
  4. ctypes, nds9, maxmod9;
  5. var
  6. sine: cint; // sine position
  7. lfo: cint; // LFO position
  8. const
  9. // waveform base frequency
  10. sine_freq = 500;
  11. // LFO frequency
  12. lfo_freq = 3;
  13. // LFO output shift amount
  14. lfo_shift = 4;
  15. // blue backdrop
  16. bg_colour = 13 shl 10;
  17. // red cpu usage
  18. cpu_colour = 31;
  19. function on_stream_request(aLength: mm_word; aDest: mm_addr; aFormat: mm_stream_formats): mm_word;
  20. var
  21. target: pcint16;
  22. len: cint;
  23. sample: cint;
  24. begin
  25. target := aDest;
  26. //------------------------------------------------------------
  27. // synthensize a sine wave with an LFO applied to the pitch
  28. // the stereo data is interleaved
  29. //------------------------------------------------------------
  30. len := aLength;
  31. while len <> 0 do
  32. begin
  33. sample := sinLerp(sine);
  34. // output sample for left
  35. target^ := sample;
  36. inc(target);
  37. // output inverted sample for right
  38. target^ := -sample;
  39. inc(target);
  40. sine := sine + sine_freq + (sinLerp(lfo) shr lfo_shift);
  41. lfo := (lfo + lfo_freq);
  42. dec(len);
  43. end;
  44. result := aLength;
  45. end;
  46. var
  47. sys: mm_ds_system;
  48. mystream: mm_stream;
  49. begin
  50. //----------------------------------------------------------------
  51. // print out some stuff
  52. //----------------------------------------------------------------
  53. consoleDemoInit();
  54. iprintf( #10' Maxmod Streaming Example '#10);
  55. //----------------------------------------------------------------
  56. // initialize maxmod without any soundbank (unusual setup)
  57. //----------------------------------------------------------------
  58. sys.mod_count := 0;
  59. sys.samp_count := 0;
  60. sys.mem_bank := nil;
  61. sys.fifo_channel := FIFO_MAXMOD;
  62. mmInit( @sys );
  63. //----------------------------------------------------------------
  64. // open stream
  65. //----------------------------------------------------------------
  66. mystream.sampling_rate := 25000; // sampling rate = 25khz
  67. mystream.buffer_length := 1200; // buffer length = 1200 samples
  68. mystream.callback := @on_stream_request; // set callback function
  69. mystream.format := MM_STREAM_16BIT_STEREO; // format = stereo 16-bit
  70. mystream.timer := MM_TIMER0; // use hardware timer 0
  71. mystream.manual := 1; // use manual filling
  72. mmStreamOpen( @mystream );
  73. //----------------------------------------------------------------
  74. // when using 'automatic' filling, your callback will be triggered
  75. // every time half of the wave buffer is processed.
  76. //
  77. // so:
  78. // 25000 (rate)
  79. // ----- = ~21 Hz for a full pass, and ~42hz for half pass
  80. // 1200 (length)
  81. //----------------------------------------------------------------
  82. // with 'manual' filling, you must call mmStreamUpdate
  83. // periodically (and often enough to avoid buffer underruns)
  84. //----------------------------------------------------------------
  85. SetYtrigger( 0 );
  86. irqEnable( IRQ_VCOUNT );
  87. while true do
  88. begin
  89. // wait until line 0
  90. swiIntrWait( 0, IRQ_VCOUNT);
  91. // update stream
  92. mmStreamUpdate();
  93. // restore backdrop (some lines were drawn with another colour to show cpu usage)
  94. BG_PALETTE_SUB[0] := bg_colour;
  95. // wait until next frame
  96. swiWaitForVBlank();
  97. // set backdrop to show cpu usage
  98. BG_PALETTE_SUB[0] := cpu_colour;
  99. end;
  100. end.