mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-11 16:37:45 -04:00
plugins: midi: remove HW_SAMPR_CAPS usage
Change-Id: Ie4962cf6d4f2f9078fa348f8f6f638cfbc0047a5
This commit is contained in:
parent
e923b354a6
commit
9c708e3876
5 changed files with 75 additions and 82 deletions
|
|
@ -381,6 +381,8 @@
|
||||||
|
|
||||||
struct MIDIfile * mf IBSS_ATTR;
|
struct MIDIfile * mf IBSS_ATTR;
|
||||||
|
|
||||||
|
int sample_rate IBSS_ATTR;
|
||||||
|
int max_voices IBSS_ATTR;
|
||||||
int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */
|
int number_of_samples IBSS_ATTR; /* the number of samples in the current tick */
|
||||||
int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */
|
int playing_time IBSS_ATTR; /* How many seconds into the file have we been playing? */
|
||||||
int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */
|
int samples_this_second IBSS_ATTR; /* How many samples produced during this second so far? */
|
||||||
|
|
@ -490,11 +492,61 @@ static void get_more(const void** start, size_t* size)
|
||||||
*size = samples_in_buf*sizeof(int32_t);
|
*size = samples_in_buf*sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct mixer_play_cbs mixer_cbs = {
|
||||||
|
.get_more = get_more,
|
||||||
|
/* TODO: update sample_rate and max_voices on sampr_changed() */
|
||||||
|
};
|
||||||
|
|
||||||
|
UNUSED_ATTR static int find_min_sampr_ge_22(void)
|
||||||
|
{
|
||||||
|
const struct pcm_sink_caps* caps = rb->pcm_current_sink_caps();
|
||||||
|
int ret = caps->samprs[0];
|
||||||
|
for (size_t i = 1; i < caps->num_samprs; i += 1)
|
||||||
|
{
|
||||||
|
/* caps->samprs is in descending order */
|
||||||
|
if (caps->samprs[i] >= SAMPR_22)
|
||||||
|
ret = caps->samprs[i];
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int midimain(const void * filename)
|
static int midimain(const void * filename)
|
||||||
{
|
{
|
||||||
int a, notes_used, vol;
|
int a, notes_used, vol;
|
||||||
bool is_playing = true; /* false = paused */
|
bool is_playing = true; /* false = paused */
|
||||||
|
|
||||||
|
/* decide sample_rate and max_voices */
|
||||||
|
#if defined(SIMULATOR) /* Simulator requires 44100Hz, and we can afford to use more voices */ || \
|
||||||
|
(CONFIG_PLATFORM & PLATFORM_HOSTED) /* All hosted targets have CPU to spare */ || \
|
||||||
|
defined(CPU_MIPS) /* All MIPS targets are pretty fast */
|
||||||
|
sample_rate = SAMPR_44;
|
||||||
|
max_voices = 48;
|
||||||
|
#elif defined(CPU_PP)
|
||||||
|
/* Some of the pp based targets can't handle too many voices
|
||||||
|
mainly because they have to use 44100Hz sample rate, this could be
|
||||||
|
improved to increase max_voices for targets that can do 22kHz */
|
||||||
|
sample_rate = find_min_sampr_ge_22();
|
||||||
|
max_voices = sample_rate == SAMPR_22 ? 24 : 16;
|
||||||
|
#elif defined(CPU_ARM)
|
||||||
|
/* ARMv4 targets are slow, but treat everything else as fast */
|
||||||
|
#if (ARM_ARCH >= 6)
|
||||||
|
sample_rate = SAMPR_44;
|
||||||
|
max_voices = 32;
|
||||||
|
#elif (ARM_ARCH >= 5)
|
||||||
|
sample_rate = find_min_sampr_ge_22();
|
||||||
|
max_voices = 32;
|
||||||
|
#else /* ie v4 */
|
||||||
|
sample_rate = find_min_sampr_ge_22();
|
||||||
|
max_voices = sample_rate == SAMPR_22 ? 24 : 16;
|
||||||
|
#endif
|
||||||
|
#else /* !CPU_ARM */
|
||||||
|
/* Treat everything else as slow */
|
||||||
|
sample_rate = find_min_sampr_ge_22();
|
||||||
|
max_voices = sample_rate == SAMPR_22 ? 24 : 16;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||||
rb->cpu_boost(true);
|
rb->cpu_boost(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -537,7 +589,7 @@ static int midimain(const void * filename)
|
||||||
rb->dsp_set_timestretch(PITCH_SPEED_100);
|
rb->dsp_set_timestretch(PITCH_SPEED_100);
|
||||||
#endif
|
#endif
|
||||||
rb->dsp_configure(dsp, DSP_SET_SAMPLE_DEPTH, 22);
|
rb->dsp_configure(dsp, DSP_SET_SAMPLE_DEPTH, 22);
|
||||||
rb->dsp_configure(dsp, DSP_SET_FREQUENCY, SAMPLE_RATE); /* 44100 22050 11025 */
|
rb->dsp_configure(dsp, DSP_SET_FREQUENCY, sample_rate); /* 44100 22050 11025 */
|
||||||
rb->dsp_configure(dsp, DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
|
rb->dsp_configure(dsp, DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -553,14 +605,14 @@ static int midimain(const void * filename)
|
||||||
midi_debug("Okay, starting sequencing");
|
midi_debug("Okay, starting sequencing");
|
||||||
|
|
||||||
bpm = mf->div*1000000/tempo;
|
bpm = mf->div*1000000/tempo;
|
||||||
number_of_samples = SAMPLE_RATE/bpm;
|
number_of_samples = sample_rate/bpm;
|
||||||
|
|
||||||
/* Skip over any junk in the beginning of the file, so start playing */
|
/* Skip over any junk in the beginning of the file, so start playing */
|
||||||
/* after the first note event */
|
/* after the first note event */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
notes_used = 0;
|
notes_used = 0;
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
if (voices[a].isUsed)
|
if (voices[a].isUsed)
|
||||||
notes_used++;
|
notes_used++;
|
||||||
tick();
|
tick();
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ 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] IBSS_ATTR;
|
struct SynthObject voices[48] IBSS_ATTR;
|
||||||
|
|
||||||
static void *alloc(int size)
|
static void *alloc(int size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,67 +27,6 @@
|
||||||
#define NBUF 2
|
#define NBUF 2
|
||||||
#define MAX_SAMPLES 512
|
#define MAX_SAMPLES 512
|
||||||
|
|
||||||
#ifdef SIMULATOR
|
|
||||||
|
|
||||||
/* Simulator requires 44100Hz, and we can afford to use more voices */
|
|
||||||
#define SAMPLE_RATE SAMPR_44
|
|
||||||
#define MAX_VOICES 48
|
|
||||||
|
|
||||||
#elif (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
|
||||||
|
|
||||||
/* All hosted targets have CPU to spare */
|
|
||||||
#define MAX_VOICES 48
|
|
||||||
#define SAMPLE_RATE SAMPR_44
|
|
||||||
|
|
||||||
#elif defined(CPU_PP)
|
|
||||||
|
|
||||||
/* Some of the pp based targets can't handle too many voices
|
|
||||||
mainly because they have to use 44100Hz sample rate, this could be
|
|
||||||
improved to increase MAX_VOICES for targets that can do 22kHz */
|
|
||||||
#define SAMPLE_RATE HW_SAMPR_MIN_GE_22
|
|
||||||
#if HW_SAMPR_CAPS & SAMPR_CAP_22
|
|
||||||
#define MAX_VOICES 24 /* General MIDI minimum */
|
|
||||||
#else
|
|
||||||
#define MAX_VOICES 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(CPU_MIPS)
|
|
||||||
|
|
||||||
/* All MIPS targets are pretty fast */
|
|
||||||
#define MAX_VOICES 48
|
|
||||||
#define SAMPLE_RATE SAMPR_44
|
|
||||||
|
|
||||||
#elif defined(CPU_ARM)
|
|
||||||
|
|
||||||
/* ARMv4 targets are slow, but treat everything else as fast */
|
|
||||||
|
|
||||||
#if (ARM_ARCH >= 6)
|
|
||||||
#define MAX_VOICES 32
|
|
||||||
#define SAMPLE_RATE SAMPR_44
|
|
||||||
#elif (ARM_ARCH >= 5)
|
|
||||||
#define MAX_VOICES 32
|
|
||||||
#define SAMPLE_RATE HW_SAMPR_MIN_GE_22
|
|
||||||
#else /* ie v4 */
|
|
||||||
#define SAMPLE_RATE HW_SAMPR_MIN_GE_22
|
|
||||||
#if HW_SAMPR_CAPS & SAMPR_CAP_22
|
|
||||||
#define MAX_VOICES 24 /* General MIDI minimum */
|
|
||||||
#else
|
|
||||||
#define MAX_VOICES 16
|
|
||||||
#endif
|
|
||||||
#endif /* ARM_ARCH < 5*/
|
|
||||||
|
|
||||||
#else /* !CPU_ARM */
|
|
||||||
|
|
||||||
/* Treat everything else as slow */
|
|
||||||
#define SAMPLE_RATE HW_SAMPR_MIN_GE_22
|
|
||||||
#if HW_SAMPR_CAPS & SAMPR_CAP_22
|
|
||||||
#define MAX_VOICES 24 /* General MIDI minimum */
|
|
||||||
#else
|
|
||||||
#define MAX_VOICES 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* Wrap it up. */
|
|
||||||
|
|
||||||
#define BYTE unsigned char
|
#define BYTE unsigned char
|
||||||
|
|
||||||
/* Data chunk ID types, returned by readID() */
|
/* Data chunk ID types, returned by readID() */
|
||||||
|
|
@ -189,7 +128,7 @@ void * readData(int file, int len);
|
||||||
#define malloc(n) my_malloc(n)
|
#define malloc(n) my_malloc(n)
|
||||||
void * my_malloc(int size);
|
void * my_malloc(int size);
|
||||||
|
|
||||||
extern struct SynthObject voices[MAX_VOICES];
|
extern struct SynthObject voices[48]; /* 48: maximum possible max_voices */
|
||||||
|
|
||||||
extern int chVol[16]; /* Channel volume */
|
extern int chVol[16]; /* Channel volume */
|
||||||
extern int chPan[16]; /* Channel panning */
|
extern int chPan[16]; /* Channel panning */
|
||||||
|
|
@ -207,6 +146,8 @@ extern struct GPatch * drumSet[128];
|
||||||
|
|
||||||
extern struct MIDIfile * mf;
|
extern struct MIDIfile * mf;
|
||||||
|
|
||||||
|
extern int sample_rate;
|
||||||
|
extern int max_voices;
|
||||||
extern int number_of_samples;
|
extern int number_of_samples;
|
||||||
extern int playing_time IBSS_ATTR;
|
extern int playing_time IBSS_ATTR;
|
||||||
extern int samples_this_second IBSS_ATTR;
|
extern int samples_this_second IBSS_ATTR;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ static inline void setVol(int ch, int vol)
|
||||||
|
|
||||||
/* If channel volume changes, we need to recalculate the volume scale */
|
/* If channel volume changes, we need to recalculate the volume scale */
|
||||||
/* factor for all voices active on this channel */
|
/* factor for all voices active on this channel */
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
if (voices[a].ch == ch)
|
if (voices[a].ch == ch)
|
||||||
setVolScale(a);
|
setVolScale(a);
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ static void findDelta(struct SynthObject * so, int ch, int note)
|
||||||
delta = (((freqtable[note+chPBNoteOffset[ch]]))); /* anywhere from 8000 to 8000000 */
|
delta = (((freqtable[note+chPBNoteOffset[ch]]))); /* anywhere from 8000 to 8000000 */
|
||||||
delta = delta * wf->sampRate; /* approx 20000 - 44000 but can vary with tuning */
|
delta = delta * wf->sampRate; /* approx 20000 - 44000 but can vary with tuning */
|
||||||
delta = (delta * chPBFractBend[ch]); /* approx 60000 - 70000 */
|
delta = (delta * chPBFractBend[ch]); /* approx 60000 - 70000 */
|
||||||
delta = delta / (SAMPLE_RATE); /* 44100 or 22050 */
|
delta = delta / (sample_rate); /* 44100 or 22050 */
|
||||||
delta = delta / (wf->rootFreq); /* anywhere from 8000 to 8000000 */
|
delta = delta / (wf->rootFreq); /* anywhere from 8000 to 8000000 */
|
||||||
|
|
||||||
/* Pitch bend is encoded as a fractional of 16 bits, hence the 16 */
|
/* Pitch bend is encoded as a fractional of 16 bits, hence the 16 */
|
||||||
|
|
@ -167,7 +167,7 @@ static void findDelta(struct SynthObject * so, int ch, int note)
|
||||||
static inline void computeDeltas(int ch)
|
static inline void computeDeltas(int ch)
|
||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
{
|
{
|
||||||
if (voices[a].isUsed && voices[a].ch == ch)
|
if (voices[a].isUsed && voices[a].ch == ch)
|
||||||
{
|
{
|
||||||
|
|
@ -210,7 +210,7 @@ static inline void pressNote(int ch, int note, int vol)
|
||||||
if(ch == 15) return;
|
if(ch == 15) return;
|
||||||
*/
|
*/
|
||||||
int a;
|
int a;
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
{
|
{
|
||||||
if (voices[a].ch == ch && voices[a].note == note)
|
if (voices[a].ch == ch && voices[a].note == note)
|
||||||
break;
|
break;
|
||||||
|
|
@ -218,7 +218,7 @@ static inline void pressNote(int ch, int note, int vol)
|
||||||
if (!voices[a].isUsed)
|
if (!voices[a].isUsed)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (a == MAX_VOICES)
|
if (a == max_voices)
|
||||||
{
|
{
|
||||||
// midi_debug("\nVoice kill");
|
// midi_debug("\nVoice kill");
|
||||||
// midi_debug("\nToo many voices playing at once. No more left");
|
// midi_debug("\nToo many voices playing at once. No more left");
|
||||||
|
|
@ -226,7 +226,7 @@ static inline void pressNote(int ch, int note, int vol)
|
||||||
// for(a=0; a<48; a++)
|
// for(a=0; a<48; a++)
|
||||||
// midi_debug("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset);
|
// midi_debug("\n#%d Ch=%d Note=%d curRate=%d curOffset=%d curPoint=%d targetOffset=%d", a, voices[a].ch, voices[a].note, voices[a].curRate, voices[a].curOffset, voices[a].curPoint, voices[a].targetOffset);
|
||||||
lastKill++;
|
lastKill++;
|
||||||
if (lastKill == MAX_VOICES)
|
if (lastKill == max_voices)
|
||||||
lastKill = 0;
|
lastKill = 0;
|
||||||
a = lastKill;
|
a = lastKill;
|
||||||
// return; /* None available */
|
// return; /* None available */
|
||||||
|
|
@ -263,7 +263,7 @@ static inline void pressNote(int ch, int note, int vol)
|
||||||
|
|
||||||
struct GWaveform * wf = drumSet[note]->waveforms[0];
|
struct GWaveform * wf = drumSet[note]->waveforms[0];
|
||||||
voices[a].wf = wf;
|
voices[a].wf = wf;
|
||||||
voices[a].delta = (((freqtable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / SAMPLE_RATE);
|
voices[a].delta = (((freqtable[note]<<FRACTSIZE) / wf->rootFreq) * wf->sampRate / sample_rate);
|
||||||
if (wf->mode & 28)
|
if (wf->mode & 28)
|
||||||
// midi_debug("\nWoah, a drum patch has a loop. Stripping the loop...");
|
// midi_debug("\nWoah, a drum patch has a loop. Stripping the loop...");
|
||||||
wf->mode = wf->mode & (255-28);
|
wf->mode = wf->mode & (255-28);
|
||||||
|
|
@ -285,7 +285,7 @@ static void releaseNote(int ch, int note)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int a;
|
int a;
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
{
|
{
|
||||||
if (voices[a].ch == ch && voices[a].note == note)
|
if (voices[a].ch == ch && voices[a].note == note)
|
||||||
{
|
{
|
||||||
|
|
@ -432,7 +432,7 @@ int tick(void)
|
||||||
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]);
|
||||||
/* midi_debug("\nMeta-Event: Tempo Set = %d", tempo); */
|
/* midi_debug("\nMeta-Event: Tempo Set = %d", tempo); */
|
||||||
bpm=mf->div*1000000/tempo;
|
bpm=mf->div*1000000/tempo;
|
||||||
number_of_samples=SAMPLE_RATE/bpm;
|
number_of_samples=sample_rate/bpm;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -446,9 +446,9 @@ int tick(void)
|
||||||
|
|
||||||
samples_this_second += number_of_samples;
|
samples_this_second += number_of_samples;
|
||||||
|
|
||||||
while (samples_this_second >= SAMPLE_RATE)
|
while (samples_this_second >= sample_rate)
|
||||||
{
|
{
|
||||||
samples_this_second -= SAMPLE_RATE;
|
samples_this_second -= sample_rate;
|
||||||
playing_time++;
|
playing_time++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,7 +471,7 @@ void seekBackward(int nsec)
|
||||||
|
|
||||||
/* Set the tempo to defalt */
|
/* Set the tempo to defalt */
|
||||||
bpm = mf->div*1000000/tempo;
|
bpm = mf->div*1000000/tempo;
|
||||||
number_of_samples = SAMPLE_RATE/bpm;
|
number_of_samples = sample_rate/bpm;
|
||||||
|
|
||||||
/* Reset the tracks to start */
|
/* Reset the tracks to start */
|
||||||
rewindFile();
|
rewindFile();
|
||||||
|
|
@ -484,7 +484,7 @@ void seekBackward(int nsec)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
notes_used = 0;
|
notes_used = 0;
|
||||||
for (a = 0; a < MAX_VOICES; a++)
|
for (a = 0; a < max_voices; a++)
|
||||||
if (voices[a].isUsed)
|
if (voices[a].isUsed)
|
||||||
notes_used++;
|
notes_used++;
|
||||||
tick();
|
tick();
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ static void readTextBlock(int file, char * buf)
|
||||||
void resetControllers()
|
void resetControllers()
|
||||||
{
|
{
|
||||||
int a=0;
|
int a=0;
|
||||||
for(a=0; a<MAX_VOICES; a++)
|
for(a=0; a<max_voices; a++)
|
||||||
{
|
{
|
||||||
voices[a].cp=0;
|
voices[a].cp=0;
|
||||||
voices[a].vol=0;
|
voices[a].vol=0;
|
||||||
|
|
@ -448,13 +448,13 @@ static inline void synthVoice(struct SynthObject * so, int32_t * out, unsigned i
|
||||||
size_t synthSamples(int32_t *buf_ptr, size_t num_samples) ICODE_ATTR;
|
size_t synthSamples(int32_t *buf_ptr, size_t num_samples) ICODE_ATTR;
|
||||||
size_t synthSamples(int32_t *buf_ptr, size_t num_samples)
|
size_t synthSamples(int32_t *buf_ptr, size_t num_samples)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
int i;
|
||||||
struct SynthObject *voicept;
|
struct SynthObject *voicept;
|
||||||
size_t nsamples = MIN(num_samples, MAX_SAMPLES);
|
size_t nsamples = MIN(num_samples, MAX_SAMPLES);
|
||||||
|
|
||||||
rb->memset(buf_ptr, 0, nsamples * 2 * sizeof(int32_t));
|
rb->memset(buf_ptr, 0, nsamples * 2 * sizeof(int32_t));
|
||||||
|
|
||||||
for(i=0; i < MAX_VOICES; i++)
|
for(i=0; i < max_voices; i++)
|
||||||
{
|
{
|
||||||
voicept=&voices[i];
|
voicept=&voices[i];
|
||||||
if(voicept->isUsed)
|
if(voicept->isUsed)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue