1 module polyplex.core.audio.syncgroup;
2 import polyplex.core.audio;
3 import polyplex.core;
4 import polyplex.utils.logging;
5 
6 /**
7     SyncGroup is a rudementary and naive form of audio synchronization for music channels.
8     It's recommended to implement your own algorithm to handle this.
9     Feel free to look at the source for some hints on how to do this.
10 */
11 public class SyncGroup {
12 private:
13     Music[] group;
14     size_t syncSource;
15     size_t combinedXruns;
16 
17 public:
18     /**
19         Creates a new SyncGroup which keeps Music instances synchronized.
20         The first track in the group is the one that will be the sync source by default.
21     */
22     this(Music[] group) {
23         this.group = group;
24     }
25 
26     ~this() {
27         destroy(group);
28     }
29 
30     /// Sets the synchronization source
31     void SetSyncSource(Music mus) {
32         foreach(i; 0 .. group.length) {
33             if (group[i] == mus) 
34                 syncSource = i;
35         }
36     }
37 
38     /// Call every frame to make sure that XRuns are handled.
39     void Update() {
40         // If Xruns have been unhandled.
41         if (combinedXruns > 0)
42             Resync();
43         
44         combinedXruns = 0;
45         foreach(audio; group) combinedXruns += audio.XRuns;
46     }
47 
48     /// Resyncronizes audio tracks
49     void Resync() {
50         size_t sourceTell = group[syncSource].Tell;
51         foreach(track; group) {
52             if (track.Playing) track.Stop();
53             track.Seek(sourceTell);
54             track.HandledXRun();
55         }
56 
57         // Once resynced, start again.
58         foreach(track; group) track.Play();
59         Logger.Debug("Resynced SyncGroup...");
60     }
61 
62     /// Play all audio tracks in the sync group
63     void Play() {
64         foreach(track; group) track.Play();
65     }
66 
67     /// Pause all audio tracks in the sync group
68     void Pause() {
69         foreach(track; group) track.Pause();
70     }
71 
72     /// Stop all audio tracks in the sync group
73     void Stop() {
74         foreach(track; group) track.Stop();
75     }
76 
77     /*
78 		PITCH
79 	*/
80     @property void Pitch(float val) { 
81         foreach(track; group) 
82             track.Pitch = val; 
83     }
84 
85 	/*
86 		GAIN
87 	*/
88     @property void Gain(float val) { 
89         foreach(track; group) 
90             track.Gain = val; 
91     }
92 }