1 /*
2    BinauralBeat.h
3    Copyright (C) 2008  Bret Logan
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 #ifndef _BINAURALBEAT_H_
21 #define _BINAURALBEAT_H_
22 
23 #ifndef TRUE
24 #define TRUE 1
25 #define FALSE 0
26 #endif
27 
28 //////VOICE TYPES////////////////////////////
29 //You can add new to the end, but NEVER change old ones; everything
30 //depends on their consistency:
31 #define BB_VOICETYPE_BINAURALBEAT   0
32 #define BB_VOICETYPE_PINKNOISE      1
33 #define BB_VOICETYPE_PCM            2   //this will always refer internally to a short int array holding interleaved stereo 44.1khz data
34 #define BB_VOICETYPE_ISOPULSE       3
35 #define BB_VOICETYPE_ISOPULSE_ALT   4
36 #define BB_VOICETYPE_WATERDROPS     5   //20110516 takes the first encountered value of beatfreq_start_HALF to set drop number
37 #define BB_VOICETYPE_RAIN           6   //20110520 variation on WATERDROPS
38 ////////////////////////////////////////////
39 
40 #define BB_PRECISION_TYPE double
41 #define BB_AUDIOSAMPLERATE          44100       //not sure what happens if you need a samplerate other than 44100
42 #define BB_EVENT_NUM_OF_ELEMENTS    5   //this MUST exactly match number of "columns" in a "row" of event data
43 #define GNAURAL_USEDEFAULTSOUNDDEVICE -255
44 
45 extern const unsigned int BB_COMPLETED;
46 extern const unsigned int BB_NEWLOOP;
47 extern const unsigned int BB_NEWENTRY;
48 extern const int BB_UPDATEPERIOD_SAMPLES;       //larger the number, less frequently I do some computationally expensive stuff. Ex: 441 = every .01 sec. @ 44100khz
49 extern const BB_PRECISION_TYPE BB_TWO_PI;
50 extern const BB_PRECISION_TYPE BB_SAMPLE_FACTOR;
51 extern const int BB_SIN_SCALER; // factors max output of sin() to fit a short (0x3fff)
52 
53 //Main Structures:
54 typedef struct
55 {
56  BB_PRECISION_TYPE duration;
57  unsigned int AbsoluteStart_samples;    //total sample count at start of entry. about 27 hours possible with uint
58  unsigned int AbsoluteEnd_samples;      //total sample count at end of entry. about 27 hours possible with uint
59  BB_PRECISION_TYPE volL_start;
60  BB_PRECISION_TYPE volL_end;
61  BB_PRECISION_TYPE volL_spread;
62  BB_PRECISION_TYPE volR_start;
63  BB_PRECISION_TYPE volR_end;
64  BB_PRECISION_TYPE volR_spread;
65  //== Following names reflect BB_VOICETYPE_BINAURALBEAT, but get used for arbitrarily for other voice types:
66  BB_PRECISION_TYPE basefreq_start;
67  BB_PRECISION_TYPE basefreq_end;
68  BB_PRECISION_TYPE basefreq_spread;
69  BB_PRECISION_TYPE beatfreq_start_HALF; //for a Beat Freq of 1.0, you'd make this 0.5. Done for calculation speed
70  BB_PRECISION_TYPE beatfreq_end_HALF;   //.5 the Beat Freq of the next Event (or first event if there is no next).
71  BB_PRECISION_TYPE beatfreq_spread_HALF;        //this is the difference between start_HALF and end_HALF
72  BB_PRECISION_TYPE LastPositionL;
73  BB_PRECISION_TYPE LastPositionR;
74 } BB_EventData;
75 
76 typedef struct
77 {
78  float count;
79  float decrement;
80  float stereoMix;
81 } BB_Waterdrop;
82 
83 typedef struct
84 {
85  int id;                        // 0,1,2,...
86  int type;                      //masks: BB_VOICETYPE_BINAURALBEAT, BB_VOICETYPE_PINKNOISE, BB_VOICETYPE_PCM
87  int mute;                      //TRUE or FALSE
88  int mono;                      //TRUE or FALSE [added 20100614]
89  BB_PRECISION_TYPE TotalDuration;       //NOTE: this is strictly the duration of this voice, which may or may not be the same as BB_TotalDuration
90  int EntryCount;
91  int CurEntry;                  //this will always hold the current entry being processed in voice
92  BB_EventData *Entry;
93  BB_PRECISION_TYPE CurVolL;
94  BB_PRECISION_TYPE CurVolR;
95  //the rest are all Voice-type specific data, to be used in any way appropriate for their kind of voice:
96  BB_PRECISION_TYPE cur_basefreq;        //BB_VOICETYPE_BINAURALBEAT: cur_basefreq;
97  BB_PRECISION_TYPE cur_beatfreq;        //BB_VOICETYPE_BINAURALBEAT: a freq snapshot in Hz of actual beat being generated
98  BB_PRECISION_TYPE cur_beatfreqL_factor;        //BB_VOICETYPE_BINAURALBEAT: cur_beatfreqL_factor;
99  BB_PRECISION_TYPE cur_beatfreqR_factor;        //BB_VOICETYPE_BINAURALBEAT: cur_beatfreqR_factor;
100  int cur_beatfreq_phasesamplecount;     //decremented to determine where in phase we are for binaural and isochronic (also calls user func if !=NULL)
101  int cur_beatfreq_phasesamplecount_start;       //updated each time a beatfreq changes to load cur_beatfreq_phasesamplecount
102  int cur_beatfreq_phaseflag;    //toggles between TRUE/FALSE every BB cycle (useful for triggering external stimuli)
103  BB_PRECISION_TYPE cur_beatfreq_phaseenvelope;  //BB_VOICETYPE_BINAURALBEAT: snapshot between 0 and 2 of phase data of BB frequency
104  BB_PRECISION_TYPE sinPosL;     //BB_VOICETYPE_BINAURALBEAT: sinPosL; phase info for left channel
105  BB_PRECISION_TYPE sinPosR;     //BB_VOICETYPE_BINAURALBEAT: sinPosR; phase info for right channel
106  BB_PRECISION_TYPE sinL;        //BB_VOICETYPE_BINAURALBEAT: sinL; instantaneous sin being used for the sample's left channel
107  BB_PRECISION_TYPE sinR;        //BB_VOICETYPE_BINAURALBEAT: sinR; instantaneous sin being used for the sample's right channel
108  int noiseL;                    //BB_VOICETYPE_PINKNOISE: instantaneous noise value left sample
109  int noiseR;                    //BB_VOICETYPE_PINKNOISE: instantaneous noise value left sample
110  //== Following is only used for BB_VOICETYPE_PCM:
111  int *PCM_samples;              //this is an int array holding stereo 44.1khz data, created by user (and MUST BE free'd by user too). Set to NULL if it holds no data.
112  unsigned int PCM_samples_size; //this is the number of elements in PCM_samples (in ints), also used for Waterdrops
113  unsigned int PCM_samples_currentcount; //this holds current place in the array
114  BB_Waterdrop *Drop;            //20110516
115 } BB_VoiceData;
116 
117 //END Main Structures
118 
119 //===============The important variables=====================
120 extern BB_VoiceData *BB_Voice;  // the biggie, used to load data
121 extern BB_PRECISION_TYPE BB_TotalDuration;      //total runtime in seconds of longest voice - USER MUST BE SURE TO ZERO BB_TotalDuration if resetting all voices
122 extern unsigned int BB_CurrentSampleCount;      //index of current sample count; can be set (to FF or RW through schedule)
123 extern unsigned int BB_CurrentSampleCountLooped;        //This is not used internally; just a courtesy to code using BB, keeping big
124 extern int BB_VoiceCount;       //can be read, but not set manually (use BB_InitVoices()).
125 extern unsigned int BB_InfoFlag;
126 extern int BB_LoopCount;        //This IS used -- set to 1 to do one pass before BB sets BB_InfoFlag to BB_COMPLETED
127 extern int BB_Loops;            //This is used whenever BB_Reset() is called, and sets BB_LoopCount (like when writing a WAV file, for instance);
128 extern const BB_PRECISION_TYPE BB_DefaultBBSched[];     //This is totally arbitrary, just to be sure something valid exists at start
129 extern BB_PRECISION_TYPE BB_VolumeOverall_left;
130 extern BB_PRECISION_TYPE BB_VolumeOverall_right;
131 extern int BB_StereoSwap;       //set true to swap left and right stereo channels
132 extern int BB_Mono;             //set true to mix and halve left and right stereo channels
133 extern unsigned int BB_FileByteCount;   //ultimately keeps count of total count of bytes currently written
134 extern int BB_WriteStopFlag;    // set to non-zero to stop a WAV file write
135 extern int BB_InCriticalLoopFlag;       //a brutish way to not do anything to BB_Voice data while audio thread is accessing data
136 
137 //IMPORTANT NOTE, new 20070831 -   BB_PauseFlag is mostly used to keep BB_MainLoop()'s thread from entering BB data while main
138 //thread is creating it. USER MUST FALSE IT WHEN DONE CREATING THE DATA:
139 extern int BB_PauseFlag;        //USER MUST FALSE THIS WHEN DONE CREATING THEIR DATA. It gets set TRUE whenever BB_InitVoices() is called
140 extern int BB_DebugFlag;        //set to TRUE to dump debug info
141 extern void (*BB_UserSleep) (int ms);   //user sets this to their own function offering short sleep; used when BB is waiting for locked data
142 extern int BB_PeakL;            //20101014
143 extern int BB_PeakR;            //20101014
144 
145 //===============Function Declarations=====================
146 void BB_MainLoop (void *pSoundBuffer, long bufferLen);
147 int BB_InitVoices (int NumberOfVoices);
148 void BB_CleanupVoices ();
149 int BB_CalibrateVoice (int VoiceID);
150 int BB_FixVoiceDurations ();    //added 20070129 to deal with BB_TotalDuration weirdness if user illegally has different lengthed voices
151 int BB_DetermineTotalDuration ();       //added 20070129 to deal with BB_TotalDuration weirdness, but BB_FixVoiceDurations() solved it
152 void BB_LoadDefaultVoice (int VoiceID);
153 int BB_WriteWAVFile (char *szFilename); //call this to write a WAV file from start of current schedule
154 int BB_WriteWAVToStream (FILE * stream);        //user can call this if they want to send a WAV to any specific stream
155 void BB_WriteWAVHeaderToStream (FILE * stream); //internal use only
156 void BB_SeedRand (unsigned int i1, unsigned int i2);
157 int BB_Rand ();
158 double BB_Rand_pm ();
159 inline int BB_LoPass (int *staticvar, int randomnumber);        //20110506, weird lo-pass filter essentially
160 inline int BB_PowerLaw (int randomnumber, int rand_max, int max_out);
161 void BB_NullAllPCMData ();      //this is for the user; never called internally. when PCM_samples == NULL, it is silenced
162 void BB_Reset ();
163 inline void BB_ResetAllVoices ();       // zeros all CurEntry's
164 int BB_SetupVoice (int VoiceID, // Array index for a BB_Voice created by BB_InitVoices()
165                    int VoiceType,       // A BB_VOICETYPE defined above
166                    int mute,    //TRUE or FALSE
167                    int mono,    //TRUE or FALSE [added 20100614]
168                    int NumberOfEvents); //how many events in your array
169 extern void (*BB_UserFunc) (int voice);
170 void BB_Water (int voice, short *array, int arraylen, float Lowcut);
171 short *BB_WaterInit (int arraylen, float pitch);
172 void BB_WaterVoiceInit (int voice);
173 
174 #define BB_DBGFLAG if (TRUE == BB_DebugFlag)
175 #define BB_DBGOUT_STR(a,b)            BB_DBGFLAG  fprintf(stderr,"%s %d: %s %s\n",__FILE__,__LINE__,a, b);
176 #define BB_DBGOUT_INT(a,b)            BB_DBGFLAG  fprintf(stderr,"%s %d: %s %d\n",__FILE__,__LINE__,a, b);
177 #define BB_DBGOUT_DBL(a,b)            BB_DBGFLAG  fprintf(stderr,"%s %d: %s %g\n",__FILE__,__LINE__,a, b);
178 #define BB_DBGOUT_PNT(a,b)            BB_DBGFLAG  fprintf(stderr,"%s %d: %s %p\n",__FILE__,__LINE__,a,b);
179 #define BB_DBGOUT(a)                  BB_DBGFLAG  fprintf(stderr,"%s %d: %s\n",__FILE__,__LINE__,a);
180 #define BB_DBG()                      BB_DBGFLAG  fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
181 #define BB_ERROUT(a)                  BB_DBGFLAG  fprintf(stderr,"%s %d: #Error# %s\n",__FILE__,__LINE__,a);
182 
183 #endif
184