diff --git a/apps/action.c b/apps/action.c index 5f845ab272..aad5348e48 100644 --- a/apps/action.c +++ b/apps/action.c @@ -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)) diff --git a/apps/filetree.c b/apps/filetree.c index 03a4d7ca36..fc5e4d3934 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -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; diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 5b9e7270cc..b22fd789a6 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c @@ -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 */ diff --git a/apps/playback.c b/apps/playback.c index 1a638eb7c8..d2d9bb6a34 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -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) diff --git a/apps/plugin.c b/apps/plugin.c index cf015e2503..f78b6bf4e1 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -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; } diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index bc6a532f2f..8642150b18 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c @@ -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 */ diff --git a/apps/settings.c b/apps/settings.c index cc50b93869..4babe33cdb 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -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(); diff --git a/apps/settings.h b/apps/settings.h index 60d5245f1b..b0117874cc 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -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. diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 8320642947..b4a2c82200 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h @@ -112,7 +112,6 @@ enum audio_buffer_state AUDIOBUF_STATE_VOICED_ONLY = 1, /* voice-only */ }; int audio_buffer_state(void); -void audio_buffer_reset(void); #endif /* channel modes */ diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index ac8ddb1b3c..053f954767 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h @@ -126,6 +126,9 @@ void pcm_record_data(pcm_more_callback_type2 more_ready, /* Stop tranferring data into supplied buffer */ void pcm_stop_recording(void); +/* Is pcm currently recording? */ +bool pcm_is_recording(void); + /* Continue transferring data in - call during interrupt handler */ void pcm_record_more(void *start, size_t size); diff --git a/firmware/pcm.c b/firmware/pcm.c index 0b5b49ebab..19bba4143e 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c @@ -478,6 +478,11 @@ void pcm_stop_recording(void) pcm_rec_unlock(); } /* pcm_stop_recording */ +bool pcm_is_recording(void) +{ + return pcm_recording; +} + void pcm_rec_dma_stopped_callback(void) { pcm_recording = false; diff --git a/firmware/usb.c b/firmware/usb.c index eb040a60a0..ec47e0653c 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -124,18 +124,6 @@ static void usb_slave_mode(bool on) rc = disk_mount_all(); if (rc <= 0) /* no partition */ panicf("mount: %d",rc); - -#ifndef BOOTLOADER -#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \ - defined(CPU_TCC77X) || defined(CPU_TCC780X) - /* These use a static transfer buffer */ -#elif defined(USB_STORAGE) && !defined (HAVE_HARDWARE_BEEP) - /* Storage can use the audio buffer, restore it if it did to get - * keyclicks back. */ - if (audio_buffer_state() == BUFFER_STATE_TRASHED) - audio_buffer_reset(); -#endif /* USB_STORAGE */ -#endif /* BOOTLOADER */ } } #endif