Some shifting optimizations. Working code. 50% realtime.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6323 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Stepan Moskovchenko 2005-04-19 15:57:07 +00:00
parent c3d0a229cc
commit 1f5fb99819
6 changed files with 238 additions and 201 deletions

View file

@ -66,18 +66,64 @@ struct GWaveform * loadWaveform(int file)
wav->res=readData(file, 36); wav->res=readData(file, 36);
wav->data=readData(file, wav->wavSize); wav->data=readData(file, wav->wavSize);
wav->numSamples = wav->wavSize / 2;
int a=0; int a=0;
return wav;
if(wav->mode & 1 == 0) //Whoops, 8 bit
{
wav->numSamples = wav->wavSize;
//Allocate a block for the rest of it
//It should end up right after the previous one.
wav->wavSize = wav->wavSize * 2;
void * foo = allocate(wav->wavSize);
for(a=0; a<1000; a++)
printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
for(a=wav->wavSize-1; a>0; a-=2)
{
}
// int b1=wf->data[s]+((wf->mode & 2) << 6);
// return b1<<8;
}
/*
//#if !defined(SIMULATOR)
for(a=0; a<wav->wavSize; a+=2)
{
unsigned char tmp;
tmp = wav->data[2*a];
wav->data[2*a] = wav->data[2*a+1];
wav->data[2*a+1] = tmp;
}
//#endif
if(wav->mode & 2)
{
for(a=0; a<wav->wavSize/2; a++)
{
((short *) wav->data)[a] = ((short *) wav->data)[a] - 32767;
}
}
*/
//If we have a 16 bit waveform //If we have a 16 bit waveform
if(wav->mode & 1 && (wav->mode & 2)) /* if(wav->mode & 1 && (wav->mode & 2))
{ {
for(a=0; a<wav->wavSize; a+=2) //Convert it to for(a=0; a<wav->wavSize; a+=2) //Convert it to
{ {
//wav->data[a]=wav->data[a]; //+((wav->mode & 2) << 6); wav->data[a]=wav->data[a]+(1 << 7);
wav->data[a|1]=wav->data[(a)|1]+(1 << 7); wav->data[a|1]=wav->data[(a)|1]+(1 << 7);
} }
} }
*/
return wav; return wav;
} }

View file

@ -36,6 +36,7 @@ struct GWaveform
unsigned char * name; unsigned char * name;
unsigned char fractions; unsigned char fractions;
unsigned int wavSize; unsigned int wavSize;
unsigned int numSamples;
unsigned int startLoop; unsigned int startLoop;
unsigned int endLoop; unsigned int endLoop;
unsigned int sampRate; unsigned int sampRate;

View file

@ -63,33 +63,26 @@
extern struct plugin_api * rb; extern struct plugin_api * rb;
int chVol[16] IDATA_ATTR; //Channel volume
int chPanLeft[16] IDATA_ATTR; //Channel panning
int chPanRight[16] IDATA_ATTR;
int chPat[16]; //Channel patch
int chPW[16]; //Channel pitch wheel, MSB only
/*
unsigned char chVol[16]; //Channel volume unsigned char chVol[16]; //Channel volume
unsigned char chPanLeft[16]; //Channel panning unsigned char chPanLeft[16]; //Channel panning
unsigned char chPanRight[16]; unsigned char chPanRight[16];
unsigned char chPat[16]; //Channel patch unsigned char chPat[16]; //Channel patch
unsigned char chPW[16]; //Channel pitch wheel, MSB only unsigned char chPW[16]; //Channel pitch wheel, MSB only
*/
struct GPatch * gusload(char *); struct GPatch * gusload(char *);
struct GPatch * patchSet[128]; struct GPatch * patchSet[128];
struct GPatch * drumSet[128]; struct GPatch * drumSet[128];
struct SynthObject voices[MAX_VOICES];
//char myarray[80] IDATA_ATTR;
struct SynthObject
{
int tmp;
struct GWaveform * wf;
unsigned int delta;
unsigned int decay;
unsigned int cp;
unsigned char state, pstate, loopState, loopDir;
unsigned char note, vol, ch, isUsed;
int curRate, curOffset, targetOffset;
int curPoint;
};
struct Event struct Event
{ {
@ -120,6 +113,34 @@ struct MIDIfile
unsigned char patches[128]; unsigned char patches[128];
int numPatches; int numPatches;
}; };
/*
struct SynthObject
{
// int tmp;
struct GWaveform * wf;
unsigned int delta;
unsigned int decay;
unsigned int cp;
unsigned char state, loopState, loopDir;
unsigned char note, vol, ch, isUsed;
int curRate, curOffset, targetOffset;
unsigned int curPoint;
};
*/
struct SynthObject
{
// int tmp;
struct GWaveform * wf;
int delta;
int decay;
int cp;
int state, loopState, loopDir;
int note, vol, ch, isUsed;
int curRate, curOffset, targetOffset;
int curPoint;
};
struct SynthObject voices[MAX_VOICES] IDATA_ATTR;
@ -133,13 +154,16 @@ int readVarData(int file);
int midimain(void * filename); int midimain(void * filename);
//Rick's code
void *alloc(int size) void *alloc(int size)
{ {
static char *offset = NULL; static char *offset = NULL;
static int totalSize = 0; static int totalSize = 0;
char *ret; char *ret;
int remainder = size % 4;
size = size + 4-remainder;
if (offset == NULL) if (offset == NULL)
{ {
offset = rb->plugin_get_audio_buffer(&totalSize); offset = rb->plugin_get_audio_buffer(&totalSize);
@ -157,40 +181,34 @@ void *alloc(int size)
totalSize -= size + 4; totalSize -= size + 4;
return ret; return ret;
} }
//Rick's code
/* /*
void *ralloc(char *offset, int len) void *alloc(int size)
{ {
int size; static char *offset = NULL;
static int totalSize = 0;
char *ret; char *ret;
if (offset == NULL) if (offset == NULL)
{ {
return alloc(len); offset = rb->plugin_get_audio_buffer(&totalSize);
} }
size = *((unsigned int *)offset - 4); if (size + 4 > totalSize)
if (size >= 0x02000000)
{ {
return NULL; return NULL;
} }
ret = alloc(len); ret = offset + 4;
*((unsigned int *)offset) = size;
if (len < size)
{
rb->memcpy(ret, offset, len);
}
else
{
rb->memcpy(ret, offset, size);
rb->memset(ret, 0, len - size);
}
offset += size + 4;
totalSize -= size + 4;
return ret; return ret;
} }*/
*/
void * allocate(int size) void * allocate(int size)
{ {
return alloc(size); return alloc(size);
@ -222,44 +240,6 @@ int eof(int fd)
void printf(char *fmt, ...) {fmt=fmt; } void printf(char *fmt, ...) {fmt=fmt; }
/*
void *audio_bufferbase;
void *audio_bufferpointer;
unsigned int audio_buffer_free;
void *my_malloc(int size)
{
void *alloc;
if (!audio_bufferbase)
{
audio_bufferbase = audio_bufferpointer
= rb->plugin_get_audio_buffer(&audio_buffer_free);
#if MEM <= 8 && !defined(SIMULATOR)
if ((unsigned)(ovl_start_addr - (unsigned char *)audio_bufferbase)
< audio_buffer_free)
audio_buffer_free = ovl_start_addr - (unsigned char *)audio_bufferbase;
#endif
}
if (size + 4 > audio_buffer_free)
return 0;
alloc = audio_bufferpointer;
audio_bufferpointer += size + 4;
audio_buffer_free -= size + 4;
return alloc;
}
void setmallocpos(void *pointer)
{
audio_bufferpointer = pointer;
audio_buffer_free = audio_bufferpointer - audio_bufferbase;
}
*/
void exit(int code) void exit(int code)
{ {
code = code; //Stub function, kill warning for now code = code; //Stub function, kill warning for now

View file

@ -88,9 +88,30 @@ void setPW(int ch, int msb)
void pressNote(int ch, int note, int vol) void pressNote(int ch, int note, int vol)
{ {
/*
if(ch == 0) return;
// if(ch == 1) return;
if(ch == 2) return;
if(ch == 3) return;
if(ch == 4) return;
if(ch == 5) return;
if(ch == 6) return;
if(ch == 7) return;
if(ch == 8) return;
if(ch == 9) return;
if(ch == 10) return;
if(ch == 11) return;
if(ch == 12) return;
if(ch == 13) return;
if(ch == 14) return;
if(ch == 15) return;
*/
int a=0; int a=0;
for(a=0; a<MAX_VOICES; a++) for(a=0; a<MAX_VOICES; a++)
{ {
if(voices[a].ch == ch && voices[a].note == note)
break;
if(voices[a].isUsed==0) if(voices[a].isUsed==0)
break; break;
} }
@ -107,7 +128,7 @@ void pressNote(int ch, int note, int vol)
voices[a].vol=vol; voices[a].vol=vol;
voices[a].cp=0; voices[a].cp=0;
voices[a].state=STATE_ATTACK; voices[a].state=STATE_ATTACK;
voices[a].pstate=STATE_ATTACK; // voices[a].pstate=STATE_ATTACK;
voices[a].decay=255; voices[a].decay=255;
@ -170,15 +191,12 @@ void releaseNote(int ch, int note)
{ {
if(voices[a].ch == ch && voices[a].note == note) if(voices[a].ch == ch && voices[a].note == note)
{ {
//voices[a].isUsed=0;
if((voices[a].wf->mode & 28)) if((voices[a].wf->mode & 28))
{ {
voices[a].tmp=40; // voices[a].tmp=40;
// voices[a].state = STATE_RELEASE; //Ramp down // voices[a].state = STATE_RELEASE; //Ramp down
// voices[a].state = STATE_RAMPDOWN; //Ramp down // voices[a].state = STATE_RAMPDOWN; //Ramp down
// voices[a].isUsed = 0;
setPoint(&voices[a], 3); setPoint(&voices[a], 3);
} }
} }
@ -281,6 +299,9 @@ int tick(struct MIDIfile * mf)
{ {
tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]); tempo = (((short)e->evData[0])<<16)|(((short)e->evData[1])<<8)|(e->evData[2]);
printf("\nMeta-Event: Tempo Set = %d", tempo); printf("\nMeta-Event: Tempo Set = %d", tempo);
bpm=mf->div*1000000/tempo;
numberOfSamples=SAMPLE_RATE/bpm;
} }
} }
tr->delta = 0; tr->delta = 0;

View file

@ -16,8 +16,6 @@
* *
****************************************************************************/ ****************************************************************************/
extern struct plugin_api * rb; extern struct plugin_api * rb;
struct Event * getEvent(struct Track * tr, int evNum) struct Event * getEvent(struct Track * tr, int evNum)
@ -178,7 +176,20 @@ int initSynth(struct MIDIfile * mf, char * filename, char * drumConfig)
inline signed short int getSample(struct GWaveform * wf, unsigned int s) int currentVoice IDATA_ATTR;
struct SynthObject * so IDATA_ATTR;
struct GWaveform * wf IDATA_ATTR;
int s IDATA_ATTR;
short s1 IDATA_ATTR;
short s2 IDATA_ATTR;
short sample IDATA_ATTR; //For synthSample
unsigned int cpShifted IDATA_ATTR;
unsigned char b1 IDATA_ATTR;
unsigned char b2 IDATA_ATTR;
inline int getSample(int s)
{ {
//16 bit samples //16 bit samples
@ -186,24 +197,23 @@ inline signed short int getSample(struct GWaveform * wf, unsigned int s)
{ {
if(s<<1 >= wf->wavSize) if(s<<1 >= wf->wavSize)
{
printf("\n!!!!! %d \t %d", s<<1, wf->wavSize);
return 0; return 0;
}
// signed short a = ((short *)wf->data)[s];
/*
* Probably put the signed/unsigned and and 8-16 bit conversion
* into the patch loader and have it run there, once.
*/
//Sign conversion moved into guspat.c //Sign conversion moved into guspat.c
unsigned char b1=wf->data[s<<1]; //+((wf->mode & 2) << 6); b1=wf->data[s<<1]+((wf->mode & 2) << 6);
unsigned char b2=wf->data[(s<<1)|1]; //+((wf->mode & 2) << 6); b2=wf->data[(s<<1)|1]+((wf->mode & 2) << 6);
return (b1 | (b2<<8)) ; return (b1 | (b2<<8)) ;
//Get rid of this sometime
} }
else else
{ //8-bit samples { //8-bit samples
//Do we even have anything 8-bit in our set? //Do we even have anything 8-bit in our set?
unsigned char b1=wf->data[s]+((wf->mode & 2) << 6); int b1=wf->data[s]+((wf->mode & 2) << 6);
return b1<<8; return b1<<8;
} }
} }
@ -251,6 +261,12 @@ inline void setPoint(struct SynthObject * so, int pt)
*/ */
so->curRate = r<<10; so->curRate = r<<10;
//Do this here because the patches assume a 44100 sampling rate
//We've halved our sampling rate, ergo the ADSR code will be
//called half the time. Ergo, double the rate to keep stuff
//sounding right.
so->curRate = so->curRate << 1;
so->targetOffset = so->wf->envOffset[pt]<<(20); so->targetOffset = so->wf->envOffset[pt]<<(20);
if(pt==0) if(pt==0)
@ -258,8 +274,6 @@ inline void setPoint(struct SynthObject * so, int pt)
} }
long msi=0;
inline void stopVoice(struct SynthObject * so) inline void stopVoice(struct SynthObject * so)
{ {
if(so->state == STATE_RAMPDOWN) if(so->state == STATE_RAMPDOWN)
@ -269,52 +283,38 @@ inline void stopVoice(struct SynthObject * so)
} }
int rampDown = 0;
inline signed short int synthVoice(int v) inline signed short int synthVoice()
{ {
//Probably can combine these 2 lines into one.. so = &voices[currentVoice];
//But for now, this looks more readable wf = so->wf;
// struct GPatch * pat = patchSet[chPat[voices[v].ch]];
// struct GWaveform * wf = pat->waveforms[pat->noteTable[voices[v].note]];
struct SynthObject * so = &voices[v];
struct GWaveform * wf = so->wf;
signed int s;
if(so->state != STATE_RAMPDOWN) if(so->state != STATE_RAMPDOWN)
{
if(so->loopDir==LOOPDIR_FORWARD)
{ {
so->cp += so->delta; so->cp += so->delta;
} }
else
{
so->cp -= so->delta;
}
}
if( (so->cp>>9 >= (wf->wavSize)) && (so->state != STATE_RAMPDOWN)) cpShifted = so->cp >> 10;
if( (cpShifted >= (wf->wavSize>>1)) && (so->state != STATE_RAMPDOWN))
stopVoice(so); stopVoice(so);
/* s2 = getSample((cpShifted)+1);
//Original, working, no interpolation
s=getSample(wf, (so->cp>>10));
*/
if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (cpShifted <= (wf->startLoop>>1)))
int s2=getSample(wf, (so->cp>>10)+1);
if((wf->mode & (LOOP_REVERSE|LOOP_PINGPONG)) && so->loopState == STATE_LOOPING && (so->cp>>10 <= (wf->startLoop>>1)))
{ {
if(wf->mode & LOOP_REVERSE) if(wf->mode & LOOP_REVERSE)
{ {
so->cp = (wf->endLoop)<<9; so->cp = (wf->endLoop)<<9;
s2=getSample(wf, (so->cp>>10)); cpShifted = so->cp >> 10;
s2=getSample((cpShifted));
} else } else
{
so->delta = -so->delta;
so->loopDir = LOOPDIR_FORWARD; so->loopDir = LOOPDIR_FORWARD;
} }
}
if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1)) if((wf->mode & 28) && (so->cp>>10 >= wf->endLoop>>1))
{ {
@ -322,14 +322,21 @@ inline signed short int synthVoice(int v)
if((wf->mode & (24)) == 0) if((wf->mode & (24)) == 0)
{ {
so->cp = (wf->startLoop)<<9; so->cp = (wf->startLoop)<<9;
s2=getSample(wf, (so->cp>>10)); cpShifted = so->cp >> 10;
s2=getSample((cpShifted));
} else } else
{
so->delta = -so->delta;
so->loopDir = LOOPDIR_REVERSE; so->loopDir = LOOPDIR_REVERSE;
} }
}
//Better, working, linear interpolation //Better, working, linear interpolation
int s1=getSample(wf, (so->cp>>10)); s1=getSample((cpShifted));
s = s1 + ((long)((s2 - s1) * (so->cp & 1023))>>10); s = s1 + ((signed)((s2 - s1) * (so->cp & 1023))>>10);
//ADSR COMMENT WOULD GO FROM HERE.........
if(so->curRate == 0) if(so->curRate == 0)
stopVoice(so); stopVoice(so);
@ -366,8 +373,9 @@ inline signed short int synthVoice(int v)
so->isUsed=0; //This is OK so->isUsed=0; //This is OK
s = s * (so->curOffset >> 22); s = (s * (so->curOffset >> 22) >> 6);
s = s>>6;
// ............. TO HERE
if(so->state == STATE_RAMPDOWN) if(so->state == STATE_RAMPDOWN)
@ -377,64 +385,28 @@ inline signed short int synthVoice(int v)
so->isUsed=0; so->isUsed=0;
} }
s = s * so->decay; s = s >> 9; s = s * so->decay; s = s >> 10;
return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14; return s*((signed short int)so->vol*(signed short int)chVol[so->ch])>>14;
} }
int mhL[16];
int mhR[16];
int mp=0; //Mix position, for circular array
// Was stuff for Ghetto Lowpass Filter, now deprecated.
inline void synthSample(int * mixL, int * mixR) inline void synthSample(int * mixL, int * mixR)
{ {
int a=0; // signed int leftMix=0, rightMix=0,
signed long int leftMix=0, rightMix=0, sample=0; *mixL = 0;
for(a=0; a<MAX_VOICES; a++) *mixR = 0;
for(currentVoice=0; currentVoice<MAX_VOICES; currentVoice++)
{ {
if(voices[a].isUsed==1) if(voices[currentVoice].isUsed==1)
{ {
sample = synthVoice(a); sample = synthVoice(currentVoice);
*mixL += (sample*chPanLeft[voices[currentVoice].ch])>>7;
leftMix += (sample*chPanLeft[voices[a].ch])>>7; *mixR += (sample*chPanRight[voices[currentVoice].ch])>>7;
rightMix += (sample*chPanRight[voices[a].ch])>>7;
} }
} }
//TODO: Automatic Gain Control, anyone? //TODO: Automatic Gain Control, anyone?
//Or, should this be implemented on the DSP's output volume instead? //Or, should this be implemented on the DSP's output volume instead?
*mixL = leftMix;
*mixR = rightMix;
return; //No more ghetto lowpass filter.. linear intrpolation works well. return; //No more ghetto lowpass filter.. linear intrpolation works well.
// HACK HACK HACK
// This is the infamous Ghetto Lowpass Filter
// Now that I have linear interpolation, it should not be needed anymore.
/*
mp++;
if(mp==4)
mp=0;
mhL[mp]=leftMix;
mhR[mp]=rightMix;
*mixL = 0;
*mixR = 0;
for(a=0; a<4; a++)
{
*mixL += mhL[a];
*mixR += mhR[a];
}
*mixL = *mixL>>4;
*mixR = *mixR>>4;
*/
// END HACK END HACK END HACK
} }

View file

@ -16,7 +16,7 @@
* *
****************************************************************************/ ****************************************************************************/
#define SAMPLE_RATE 48000 #define SAMPLE_RATE 22050
#define MAX_VOICES 100 #define MAX_VOICES 100
@ -37,6 +37,12 @@
#include "../../plugin.h" #include "../../plugin.h"
#include "lib/xxx2wav.h"
int numberOfSamples IDATA_ATTR;
long bpm;
#include "midi/midiutil.c" #include "midi/midiutil.c"
#include "midi/guspat.h" #include "midi/guspat.h"
#include "midi/guspat.c" #include "midi/guspat.c"
@ -46,7 +52,6 @@
#include "lib/xxx2wav.h"
int fd=-1; //File descriptor where the output is written int fd=-1; //File descriptor where the output is written
@ -58,6 +63,7 @@ struct plugin_api * rb;
enum plugin_status plugin_start(struct plugin_api* api, void* parameter) enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{ {
TEST_PLUGIN_API(api); TEST_PLUGIN_API(api);
@ -80,6 +86,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
return PLUGIN_OK; return PLUGIN_OK;
} }
signed char outputBuffer[3000] IDATA_ATTR; //signed char.. gonna run out of iram ... !
int currentSample IDATA_ATTR;
int outputBufferPosition IDATA_ATTR;
int outputSampleOne IDATA_ATTR;
int outputSampleTwo IDATA_ATTR;
int midimain(void * filename) int midimain(void * filename)
{ {
@ -89,9 +103,6 @@ int midimain(void * filename)
rb->splash(HZ/5, true, "LOADING MIDI"); rb->splash(HZ/5, true, "LOADING MIDI");
struct MIDIfile * mf = loadFile(filename); struct MIDIfile * mf = loadFile(filename);
long bpm, nsmp, l;
int bp=0;
rb->splash(HZ/5, true, "LOADING PATCHES"); rb->splash(HZ/5, true, "LOADING PATCHES");
if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1) if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
@ -125,7 +136,7 @@ int midimain(void * filename)
samp=arg; samp=arg;
#else #else
file_info_struct file_info; file_info_struct file_info;
file_info.samplerate = 48000; file_info.samplerate = SAMPLE_RATE;
file_info.infile = fd; file_info.infile = fd;
file_info.channels = 2; file_info.channels = 2;
file_info.bitspersample = 16; file_info.bitspersample = 16;
@ -134,12 +145,11 @@ int midimain(void * filename)
#endif #endif
rb->splash(HZ/5, true, " START PLAYING "); rb->splash(HZ/5, true, " Starting Playback ");
signed char buf[3000];
// tick() will do one MIDI clock tick. Then, there's a loop here that // tick() will do one MIDI clock tick. Then, there's a loop here that
// will generate the right number of samples per MIDI tick. The whole // will generate the right number of samples per MIDI tick. The whole
@ -152,49 +162,56 @@ int midimain(void * filename)
printf("\nOkay, starting sequencing"); printf("\nOkay, starting sequencing");
currentSample=0; //Sample counting variable
outputBufferPosition = 0;
bpm=mf->div*1000000/tempo;
numberOfSamples=SAMPLE_RATE/bpm;
//Tick() will return 0 if there are no more events left to play //Tick() will return 0 if there are no more events left to play
while(tick(mf)) while(tick(mf))
{ {
//Some annoying math to compute the number of samples //Some annoying math to compute the number of samples
//to syntehsize per each MIDI tick. //to syntehsize per each MIDI tick.
bpm=mf->div*1000000/tempo;
nsmp=SAMPLE_RATE/bpm;
//Yes we need to do this math each time because the tempo //Yes we need to do this math each time because the tempo
//could have changed. //could have changed.
// On second thought, this can be moved to the event that // On second thought, this can be moved to the event that
//recalculates the tempo, to save a little bit of CPU time. //recalculates the tempo, to save a little bit of CPU time.
for(l=0; l<nsmp; l++) for(currentSample=0; currentSample<numberOfSamples; currentSample++)
{ {
int s1, s2;
synthSample(&s1, &s2); synthSample(&outputSampleOne, &outputSampleTwo);
//16-bit audio because, well, it's better //16-bit audio because, well, it's better
// But really because ALSA's OSS emulation sounds extremely // But really because ALSA's OSS emulation sounds extremely
//noisy and distorted when in 8-bit mode. I still do not know //noisy and distorted when in 8-bit mode. I still do not know
//why this happens. //why this happens.
buf[bp]=s1&0XFF; // Low byte first outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
bp++; outputBufferPosition++;
buf[bp]=s1>>8; //High byte second outputBuffer[outputBufferPosition]=outputSampleOne>>8; //High byte second
bp++; outputBufferPosition++;
buf[bp]=s2&0XFF; // Low byte first outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
bp++; outputBufferPosition++;
buf[bp]=s2>>8; //High byte second outputBuffer[outputBufferPosition]=outputSampleTwo>>8; //High byte second
bp++; outputBufferPosition++;
//As soon as we produce 2000 bytes of sound, //As soon as we produce 2000 bytes of sound,
//write it to the sound card. Why 2000? I have //write it to the sound card. Why 2000? I have
//no idea. It's 1 AM and I am dead tired. //no idea. It's 1 AM and I am dead tired.
if(bp>=2000) if(outputBufferPosition>=2000)
{ {
rb->write(fd, buf, 2000); rb->write(fd, outputBuffer, 2000);
bp=0; outputBufferPosition=0;
} }
} }
} }