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