Advertisement
apexsquirt

[C++ / GrAPic] Ball physics with sound

Feb 17th, 2020
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.30 KB | None | 0 0
  1. #include <SDL_audio.h>
  2. #include <Grapic.h>
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include <queue>
  8. #include <cmath>
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20. // yoinked from jrok's code (https://stackoverflow.com/users/947836/jrok)
  21.  
  22. const int AMPLITUDE = 28000;
  23. const int FREQUENCY = 44100;
  24.  
  25. struct BeepObject {
  26.     double freq;
  27.     int samplesLeft;
  28. };
  29.  
  30. class Beeper {
  31. private:
  32.     double v;
  33.     std::queue<BeepObject> beeps;
  34. public:
  35.     Beeper();
  36.     ~Beeper();
  37.     void beep(double freq, int duration);
  38.     void generateSamples(Sint16 *stream, int length);
  39.     void wait();
  40. };
  41.  
  42. void audio_callback(void*, Uint8*, int);
  43.  
  44. Beeper::Beeper() {
  45.     SDL_AudioSpec desiredSpec;
  46.  
  47.     desiredSpec.freq = FREQUENCY;
  48.     desiredSpec.format = AUDIO_S16SYS;
  49.     desiredSpec.channels = 1;
  50.     desiredSpec.samples = 2048;
  51.     desiredSpec.callback = audio_callback;
  52.     desiredSpec.userdata = this;
  53.  
  54.     SDL_AudioSpec obtainedSpec;
  55.  
  56.     // you might want to look for errors here
  57.     SDL_OpenAudio(&desiredSpec, &obtainedSpec);
  58.  
  59.     // start play audio
  60.     SDL_PauseAudio(0);
  61. }
  62.  
  63. Beeper::~Beeper() {
  64.     SDL_CloseAudio();
  65. }
  66.  
  67. double fade_out (double v, double a, double b) {
  68.     if (v < a) return AMPLITUDE;
  69.     if (v >= a and v <= b) return AMPLITUDE-(AMPLITUDE*(v-a)/(b-a));
  70.     else return 0;
  71. }
  72.  
  73. double mod (double x, double n) {
  74.     return n-(x-n*floor(x/n));
  75. }
  76.  
  77. void Beeper::generateSamples(Sint16 *stream, int length) {
  78.     int i = 0;
  79.     while (i < length) {
  80.  
  81.         if (beeps.empty()) {
  82.             while (i < length) {
  83.                 stream[i] = 0;
  84.                 i++;
  85.             }
  86.             return;
  87.         }
  88.         BeepObject& bo = beeps.front();
  89.  
  90.         int samplesToDo = std::min(i + bo.samplesLeft, length);
  91.         bo.samplesLeft -= samplesToDo - i;
  92.  
  93.         while (i < samplesToDo) {
  94.             stream[i] = AMPLITUDE * (std::sin(v * 2 * M_PI / FREQUENCY));
  95.             // vous pouvez y mettre les trucs que vous voulez, même des séries d'fourier why not
  96.             i++;
  97.             v += bo.freq;
  98.         }
  99.  
  100.         if (bo.samplesLeft == 0) {
  101.             beeps.pop();
  102.         }
  103.     }
  104. }
  105.  
  106. void Beeper::beep(double freq, int duration) {
  107.     BeepObject bo;
  108.     bo.freq = freq;
  109.     bo.samplesLeft = duration * FREQUENCY / 1000;
  110.  
  111.     SDL_LockAudio();
  112.     beeps.push(bo);
  113.     SDL_UnlockAudio();
  114. }
  115.  
  116. void Beeper::wait() {
  117.     int size;
  118.     do {
  119.         SDL_Delay(20);
  120.         SDL_LockAudio();
  121.         size = beeps.size();
  122.         SDL_UnlockAudio();
  123.     } while (size > 0);
  124.  
  125. }
  126.  
  127. void audio_callback(void *_beeper, Uint8 *_stream, int _length) {
  128.     Sint16 *stream = (Sint16*) _stream;
  129.     int length = _length / 2;
  130.     Beeper* beeper = (Beeper*) _beeper;
  131.  
  132.     beeper->generateSamples(stream, length);
  133. }
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153. using namespace grapic;
  154. const int DIMW = 900;
  155. const int MAX = 256;
  156. const float FRICTION = 0.5;
  157. const float G = 2.0*pow(10,-11)/3.0;
  158.  
  159. struct vec {
  160.     float x;
  161.     float y;
  162. };
  163.  
  164. vec mkvec (float x, float y) {
  165.     vec ret;
  166.     ret.x = x; ret.y = y;
  167.     return ret;
  168. }
  169. vec operator+ (vec a, vec b) { return mkvec(a.x+b.x,a.y+b.y); }
  170. vec operator- (vec a, vec b) { return mkvec(a.x-b.x,a.y-b.y); }
  171. void operator+= (vec &a, vec b) { a=a+b; }
  172. bool operator== (vec a, vec b) { return (a.x == b.x) and (a.y == b.y); }
  173. vec operator* (vec a, float b) { return mkvec(a.x*b,a.y*b); }
  174.  
  175. struct Particle {
  176.     vec pos;
  177.     vec v;
  178.     vec F;
  179.     float m;
  180.     int r;
  181.     int g;
  182.     int b;
  183. };
  184.  
  185. void partInit (Particle& p, vec pos, vec v, float m) {
  186.     p.m = m;
  187.     p.pos = pos;
  188.     p.v = v;
  189.     p.F = mkvec(0,0);
  190. }
  191.  
  192. void partAddForce (Particle& p, vec force) {
  193.     p.F += force;
  194. }
  195.  
  196. float cjgsqr (vec a) { return (a.x*a.x)+(a.y*a.y); }
  197.  
  198. void partUpdatePV (Particle& p, bool& b, double &Hz) {
  199.     float dt = 0.025;
  200.     vec oldpos = p.pos;
  201.     b = false;
  202.     p.v += p.F*(dt*p.m);
  203.     if (abs(p.pos.x + p.v.x*dt - DIMW/2) >= DIMW/2) { p.v.x = -p.v.x; p.v = p.v*FRICTION; b = true; }
  204.     if (abs(p.pos.y + p.v.y*dt - DIMW/2) >= DIMW/2) { p.v.y = -p.v.y; p.v = p.v*FRICTION; b = true; }
  205.     p.pos += p.v*dt; if (p.pos.y <= oldpos.y+1 and p.pos.y < 1 and oldpos.y < 1) b = false;
  206.     Hz = cjgsqr(p.v)/30 + p.pos.y/30 + 110;
  207. }
  208.  
  209. int main(int, char**) {
  210.  
  211.     srand(time(NULL));
  212.  
  213.     bool stop = false;
  214.     double Hz = 0;
  215.     Particle P[MAX];
  216.  
  217.     int nb = 100, j = 0;
  218.     float dt = 0.1;
  219.     Beeper boop;
  220.     bool b = false;
  221.     int R[MAX];
  222.  
  223.     winInit("Particules",DIMW,DIMW);
  224.     backgroundColor(0,0,0);
  225.     color(255,255,255);
  226.     pressSpace();
  227.  
  228.     loop:
  229.     for (int i = 0; i < nb; i++) {
  230.         partInit(P[i],mkvec(DIMW/2,DIMW/2),mkvec(rand()%DIMW-DIMW/2,rand()%DIMW-DIMW/2),rand()%10+1);
  231.         partAddForce(P[i],mkvec(0,-9.81));
  232.         P[i].r = rand() % 256; P[i].g = rand() % 256; P[i].b = rand() % 256;
  233.         R[i] = rand()%10+10;
  234.     }
  235.  
  236.     while (!stop) {
  237.         winClear();
  238.         for (int i = 0; i < nb; i++) {
  239.             //F(P,nb);
  240.             partUpdatePV(P[i],b,Hz);
  241.             color(P[i].r,P[i].g,P[i].b,200);
  242.             circleFill(P[i].pos.x,P[i].pos.y,R[i]);
  243.             if (b) { boop.beep(Hz,1); }
  244.         }
  245.         if (isKeyPressed(SDLK_SPACE)) {
  246.             goto loop;
  247.         }
  248.         stop = winDisplay();
  249.     }
  250.  
  251.     winQuit();
  252.     return 0;
  253.  
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement