1 class Audio
2 {
3
4 public:
5 static void init()
6 {
7 head_ = 0;
8 tail_ = 0;
9 }
10
11 // Methods...
12
13 private:
14 static int head_;
15 static int tail_;
16
17 static const int MAX_PENDING = 16;
18
19 static PlayMessage pending_[MAX_PENDING];
20 };
21
22 void Audio::playSound(SoundId id, int volume)
23 {
24 // Walk the pending requests.
25 for (int i = head_; i != tail_;
26 i = (i + 1) % MAX_PENDING)
27 {
28 if (pending_[i].id == id)
29 {
30 // Use the larger of the two volumes.
31 pending_[i].volume = max(volume, pending_[i].volume);
32
33 // Don't need to enqueue.
34 return;
35 }
36 }
37
38 assert((tail_ + 1) % MAX_PENDING != head_);
39
40 // Add to the end of the list.
41 pending_[tail_].id = id;
42 pending_[tail_].volume = volume;
43 tail_ = (tail_ + 1) % MAX_PENDING;
44 }
45
46 void Audio::update()
47 {
48 // If there are no pending requests, do nothing.
49 if (head_ == tail_) return;
50
51 ResourceId resource = loadSound(pending_[head_].id);
52 int channel = findOpenChannel();
53 if (channel == -1) return;
54 startSound(resource, channel, pending_[head_].volume);
55
56 head_ = (head_ + 1) % MAX_PENDING;
57 }