streaming.pp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. keys: cint;
  50. begin
  51. //----------------------------------------------------------------
  52. // print out some stuff
  53. //----------------------------------------------------------------
  54. consoleDemoInit();
  55. iprintf( #10' Maxmod Streaming Example '#10);
  56. //----------------------------------------------------------------
  57. // initialize maxmod without any soundbank (unusual setup)
  58. //----------------------------------------------------------------
  59. sys.mod_count := 0;
  60. sys.samp_count := 0;
  61. sys.mem_bank := nil;
  62. sys.fifo_channel := FIFO_MAXMOD;
  63. mmInit( @sys );
  64. //----------------------------------------------------------------
  65. // open stream
  66. //----------------------------------------------------------------
  67. mystream.sampling_rate := 25000; // sampling rate = 25khz
  68. mystream.buffer_length := 1200; // buffer length = 1200 samples
  69. mystream.callback := @on_stream_request; // set callback function
  70. mystream.format := MM_STREAM_16BIT_STEREO; // format = stereo 16-bit
  71. mystream.timer := MM_TIMER0; // use hardware timer 0
  72. mystream.manual := 1; // use manual filling
  73. mmStreamOpen( @mystream );
  74. //----------------------------------------------------------------
  75. // when using 'automatic' filling, your callback will be triggered
  76. // every time half of the wave buffer is processed.
  77. //
  78. // so:
  79. // 25000 (rate)
  80. // ----- = ~21 Hz for a full pass, and ~42hz for half pass
  81. // 1200 (length)
  82. //----------------------------------------------------------------
  83. // with 'manual' filling, you must call mmStreamUpdate
  84. // periodically (and often enough to avoid buffer underruns)
  85. //----------------------------------------------------------------
  86. SetYtrigger( 0 );
  87. irqEnable( IRQ_VCOUNT );
  88. while true do
  89. begin
  90. // wait until line 0
  91. swiIntrWait( 0, IRQ_VCOUNT);
  92. // update stream
  93. mmStreamUpdate();
  94. // restore backdrop (some lines were drawn with another colour to show cpu usage)
  95. BG_PALETTE_SUB[0] := bg_colour;
  96. // wait until next frame
  97. swiWaitForVBlank();
  98. //-----------------------------------------------------
  99. // get new keypad input
  100. //-----------------------------------------------------
  101. scanKeys();
  102. keys := keysDown();
  103. //-----------------------------------------------------
  104. // START: exit
  105. //-----------------------------------------------------
  106. if (keys and KEY_START) <> 0 then break;
  107. // set backdrop to show cpu usage
  108. BG_PALETTE_SUB[0] := cpu_colour;
  109. end;
  110. end.