mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Keyclick fixup take two. It is only 88 samples (2msec) long so keep a small static buffer around for beeps less than or equal to keyclick duration. This way it operates no matter the buffer state and still won't interfere with alternate PCM operations like recording or plugin playback.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19415 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
bdcdf8b5e4
commit
93572e2a9e
12 changed files with 52 additions and 63 deletions
|
|
@ -130,7 +130,7 @@ static int get_action_worker(int context, int timeout,
|
|||
/* Produce keyclick */
|
||||
if (global_settings.keyclick && !(button & BUTTON_REL))
|
||||
if (!(button & BUTTON_REPEAT) || global_settings.keyclick_repeats)
|
||||
pcmbuf_beep(4000, 2, 2500*global_settings.keyclick);
|
||||
pcmbuf_beep(4000, KEYCLICK_DURATION, 2500*global_settings.keyclick);
|
||||
#endif
|
||||
|
||||
if ((context != last_context) && ((last_button & BUTTON_REL) == 0))
|
||||
|
|
|
|||
|
|
@ -509,9 +509,6 @@ int ft_enter(struct tree_context* c)
|
|||
MAX_FILENAME);
|
||||
talk_init(); /* use voice of same language */
|
||||
splash(HZ, ID2P(LANG_LANGUAGE_LOADED));
|
||||
#if CONFIG_CODEC == SWCODEC && !defined(HAVE_HARDWARE_BEEP)
|
||||
audio_buffer_reset();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -955,25 +955,22 @@ bool pcmbuf_insert_buffer(char *buf, int count)
|
|||
#endif
|
||||
|
||||
#ifndef HAVE_HARDWARE_BEEP
|
||||
#define MINIBUF_SAMPLES (NATIVE_FREQUENCY / 1000 * KEYCLICK_DURATION)
|
||||
#define MINIBUF_SIZE (MINIBUF_SAMPLES*4)
|
||||
|
||||
/* Generates a constant square wave sound with a given frequency
|
||||
in Hertz for a duration in milliseconds. */
|
||||
void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
||||
{
|
||||
unsigned int step;
|
||||
int32_t phase;
|
||||
unsigned int step = 0xffffffffu / NATIVE_FREQUENCY * frequency;
|
||||
int32_t phase = 0;
|
||||
int16_t *bufptr, *bufstart, *bufend;
|
||||
int32_t sample;
|
||||
int nsamples;
|
||||
bool mix;
|
||||
int nsamples = NATIVE_FREQUENCY / 1000 * duration;
|
||||
bool mix = pcmbuf_read != NULL && pcmbuf_read->link != NULL;
|
||||
int i;
|
||||
|
||||
if (audio_buffer_state() == AUDIOBUF_STATE_TRASHED)
|
||||
return; /* No voice or playback = no beeping. */
|
||||
|
||||
phase = 0;
|
||||
step = 0xffffffffu / NATIVE_FREQUENCY * frequency;
|
||||
nsamples = NATIVE_FREQUENCY / 1000 * duration;
|
||||
mix = pcmbuf_read != NULL && pcmbuf_read->link != NULL;
|
||||
bufend = SKIPBYTES((int16_t *)audiobuffer, pcmbuf_size);
|
||||
|
||||
/* Find the insertion point and set bufstart to the start of it */
|
||||
if (mix)
|
||||
|
|
@ -987,21 +984,31 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
|||
/* Give 5ms clearance. */
|
||||
bufstart += NATIVE_FREQUENCY * 4 / 200;
|
||||
|
||||
/* Wrapped above? */
|
||||
if (bufstart >= bufend)
|
||||
bufstart -= pcmbuf_size;
|
||||
|
||||
/* NOTE: On some targets using hardware DMA, cache range flushing may
|
||||
* be required or the writes may not be picked up by the controller.
|
||||
* An incremental flush should be done periodically during the mixdown. */
|
||||
}
|
||||
else
|
||||
else if (nsamples <= MINIBUF_SAMPLES)
|
||||
{
|
||||
static int16_t minibuf[MINIBUF_SAMPLES*2];
|
||||
/* Use mini buffer */
|
||||
bufstart = minibuf;
|
||||
bufend = SKIPBYTES(bufstart, MINIBUF_SIZE);
|
||||
}
|
||||
else if (audio_buffer_state() != AUDIOBUF_STATE_TRASHED)
|
||||
{
|
||||
/* Use audiobuffer */
|
||||
bufstart = (int16_t *)audiobuffer;
|
||||
}
|
||||
|
||||
bufend = (int16_t *)SKIPBYTES(audiobuffer, pcmbuf_size);
|
||||
|
||||
/* Wrapped above? */
|
||||
if (bufstart >= bufend)
|
||||
bufstart -= pcmbuf_size;
|
||||
else
|
||||
{
|
||||
/* No place */
|
||||
return;
|
||||
}
|
||||
|
||||
bufptr = bufstart;
|
||||
|
||||
|
|
@ -1022,14 +1029,24 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
|
|||
}
|
||||
|
||||
pcm_play_lock();
|
||||
#ifdef HAVE_RECORDING
|
||||
pcm_rec_lock();
|
||||
#endif
|
||||
|
||||
/* Kick off playback if required */
|
||||
if (!pcm_is_playing())
|
||||
/* Kick off playback if required and it won't interfere */
|
||||
if (!pcm_is_playing()
|
||||
#ifdef HAVE_RECORDING
|
||||
&& !pcm_is_recording()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
pcm_play_data(NULL, (unsigned char *)bufstart, nsamples * 4);
|
||||
}
|
||||
|
||||
pcm_play_unlock();
|
||||
#ifdef HAVE_RECORDING
|
||||
pcm_rec_unlock();
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_HARDWARE_BEEP */
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,6 @@ enum {
|
|||
Q_AUDIO_POSTINIT,
|
||||
Q_AUDIO_FILL_BUFFER,
|
||||
Q_AUDIO_FINISH_LOAD,
|
||||
Q_AUDIO_RESTORE_BUFFER,
|
||||
Q_CODEC_REQUEST_COMPLETE,
|
||||
Q_CODEC_REQUEST_FAILED,
|
||||
|
||||
|
|
@ -491,12 +490,6 @@ int audio_buffer_state(void)
|
|||
return buffer_state;
|
||||
}
|
||||
|
||||
void audio_buffer_reset(void)
|
||||
{
|
||||
LOGFQUEUE("audio_queue >| Q_AUDIO_RESTORE_BUFFER");
|
||||
queue_send(&audio_queue, Q_AUDIO_RESTORE_BUFFER, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
unsigned char *audio_get_recording_buffer(size_t *buffer_size)
|
||||
{
|
||||
|
|
@ -2396,12 +2389,6 @@ static void audio_thread(void)
|
|||
audio_finish_load_track();
|
||||
break;
|
||||
|
||||
case Q_AUDIO_RESTORE_BUFFER:
|
||||
LOGFQUEUE("audio < Q_AUDIO_RESTORE_BUFFER");
|
||||
if (buffer_state != AUDIOBUF_STATE_INITIALIZED)
|
||||
audio_reset_buffer();
|
||||
break;
|
||||
|
||||
case Q_AUDIO_PLAY:
|
||||
LOGFQUEUE("audio < Q_AUDIO_PLAY");
|
||||
if (playing && ev.data <= 0)
|
||||
|
|
|
|||
|
|
@ -785,12 +785,6 @@ int plugin_load(const char* plugin, const void* parameter)
|
|||
break;
|
||||
}
|
||||
|
||||
#if CONFIG_CODEC == SWCODEC && !defined (HAVE_HARDWARE_BEEP)
|
||||
/* Did the plugin trash the buffer? Restore it. */
|
||||
if (audio_buffer_state() == AUDIOBUF_STATE_TRASHED)
|
||||
audio_buffer_reset();
|
||||
#endif
|
||||
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1167,10 +1167,6 @@ static void pcmrec_close(void)
|
|||
pcm_close_recording();
|
||||
reset_hardware();
|
||||
audio_remove_encoder();
|
||||
#ifndef HAVE_HARDWARE_BEEP
|
||||
/* Restore keyclicks */
|
||||
audio_buffer_reset();
|
||||
#endif
|
||||
} /* pcmrec_close */
|
||||
|
||||
/* PCMREC_OPTIONS */
|
||||
|
|
|
|||
|
|
@ -885,9 +885,6 @@ void settings_apply(bool read_disk)
|
|||
global_settings.lang_file);
|
||||
lang_load(buf);
|
||||
talk_init(); /* use voice of same language */
|
||||
#if CONFIG_CODEC == SWCODEC && !defined(HAVE_HARDWARE_BEEP)
|
||||
audio_buffer_reset();
|
||||
#endif
|
||||
}
|
||||
/* load the icon set */
|
||||
icons_init();
|
||||
|
|
|
|||
|
|
@ -177,6 +177,12 @@ enum { ALARM_START_WPS = 0,
|
|||
#endif
|
||||
|
||||
#endif /* HAVE_RTC_ALARM */
|
||||
|
||||
/* Keyclick stuff */
|
||||
|
||||
/* Not really a setting but several files should stay synced */
|
||||
#define KEYCLICK_DURATION 2
|
||||
|
||||
/** virtual pointer stuff.. move to another .h maybe? **/
|
||||
/* These define "virtual pointers", which could either be a literal string,
|
||||
or a mean a string ID if the pointer is in a certain range.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue