diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-07-17 00:01:32 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-07-24 21:20:13 +0000 |
commit | 8cb555460ff79e636a7907fb2589e16db98c8600 (patch) | |
tree | 930a3878c7641c9ce045b24f0ade1309e36d5806 /apps/talk.c | |
parent | 0c4f89370d05056faa789aa9cabcccc4e509fb9f (diff) | |
download | rockbox-8cb555460ff79e636a7907fb2589e16db98c8600.tar.gz rockbox-8cb555460ff79e636a7907fb2589e16db98c8600.zip |
[3/4] Completely remove HWCODEC support
'swcodec' is now always set (and recording_swcodec for recording-capable
units) in feature.txt so the manual and language strings don't need to
all be fixed up.
Change-Id: Ib2c9d5d157af8d33653e2d4b4a12881b9aa6ddb0
Diffstat (limited to 'apps/talk.c')
-rw-r--r-- | apps/talk.c | 105 |
1 files changed, 6 insertions, 99 deletions
diff --git a/apps/talk.c b/apps/talk.c index 3aedaf34ec..4b65700a5d 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -32,11 +32,7 @@ | |||
32 | #include "settings.h" | 32 | #include "settings.h" |
33 | #include "settings_list.h" | 33 | #include "settings_list.h" |
34 | #include "splash.h" | 34 | #include "splash.h" |
35 | #if CONFIG_CODEC == SWCODEC | ||
36 | #include "voice_thread.h" | 35 | #include "voice_thread.h" |
37 | #else | ||
38 | #include "mp3_playback.h" | ||
39 | #endif | ||
40 | #include "audio.h" | 36 | #include "audio.h" |
41 | #include "lang.h" | 37 | #include "lang.h" |
42 | #include "talk.h" | 38 | #include "talk.h" |
@@ -107,7 +103,7 @@ struct voicefile_header /* file format of our voice file */ | |||
107 | 103 | ||
108 | /***************** Globals *****************/ | 104 | /***************** Globals *****************/ |
109 | 105 | ||
110 | #if (CONFIG_CODEC == SWCODEC && MEMORYSIZE <= 2) | 106 | #if MEMORYSIZE <= 2 |
111 | /* On low memory swcodec targets the entire voice file wouldn't fit in memory | 107 | /* On low memory swcodec targets the entire voice file wouldn't fit in memory |
112 | * together with codecs, so we load clips each time they are accessed. */ | 108 | * together with codecs, so we load clips each time they are accessed. */ |
113 | #define TALK_PROGRESSIVE_LOAD | 109 | #define TALK_PROGRESSIVE_LOAD |
@@ -131,15 +127,10 @@ static bool force_enqueue_next; /* enqueue next utterance even if enqueue is fal | |||
131 | static int queue_write; /* write index of queue, by application */ | 127 | static int queue_write; /* write index of queue, by application */ |
132 | static int queue_read; /* read index of queue, by ISR context */ | 128 | static int queue_read; /* read index of queue, by ISR context */ |
133 | static enum talk_status talk_status = TALK_STATUS_OK; | 129 | static enum talk_status talk_status = TALK_STATUS_OK; |
134 | #if CONFIG_CODEC == SWCODEC | ||
135 | /* protects queue_read, queue_write and thumbnail_buf_used */ | 130 | /* protects queue_read, queue_write and thumbnail_buf_used */ |
136 | static struct mutex queue_mutex SHAREDBSS_ATTR; | 131 | static struct mutex queue_mutex SHAREDBSS_ATTR; |
137 | #define talk_queue_lock() ({ mutex_lock(&queue_mutex); }) | 132 | #define talk_queue_lock() ({ mutex_lock(&queue_mutex); }) |
138 | #define talk_queue_unlock() ({ mutex_unlock(&queue_mutex); }) | 133 | #define talk_queue_unlock() ({ mutex_unlock(&queue_mutex); }) |
139 | #else | ||
140 | #define talk_queue_lock() ({ }) | ||
141 | #define talk_queue_unlock() ({ }) | ||
142 | #endif /* CONFIG_CODEC */ | ||
143 | static int sent; /* how many bytes handed over to playback, owned by ISR */ | 134 | static int sent; /* how many bytes handed over to playback, owned by ISR */ |
144 | static unsigned char curr_hd[3]; /* current frame header, for re-sync */ | 135 | static unsigned char curr_hd[3]; /* current frame header, for re-sync */ |
145 | static unsigned char last_lang[MAX_FILENAME+1]; /* name of last used lang file (in talk_init) */ | 136 | static unsigned char last_lang[MAX_FILENAME+1]; /* name of last used lang file (in talk_init) */ |
@@ -186,16 +177,8 @@ static int move_callback(int handle, void *current, void *new) | |||
186 | 177 | ||
187 | static struct mutex read_buffer_mutex; | 178 | static struct mutex read_buffer_mutex; |
188 | 179 | ||
189 | 180 | static inline bool check_audio_status(void) | |
190 | /* on HWCODEC only voice xor audio can be active at a time */ | ||
191 | static bool check_audio_status(void) | ||
192 | { | 181 | { |
193 | #if CONFIG_CODEC != SWCODEC | ||
194 | if (audio_status()) /* busy, buffer in use */ | ||
195 | return false; | ||
196 | /* ensure playback is given up on the buffer */ | ||
197 | audio_hard_stop(); | ||
198 | #endif | ||
199 | return true; | 182 | return true; |
200 | } | 183 | } |
201 | 184 | ||
@@ -670,20 +653,16 @@ static bool load_voicefile_data(int fd) | |||
670 | return true; | 653 | return true; |
671 | } | 654 | } |
672 | 655 | ||
673 | /* Use a static buffer to avoid difficulties with buflib during DMA | 656 | /* Use a static buffer to avoid difficulties with buflib during |
674 | * (hwcodec)/buffer passing to the voice_thread (swcodec). Clips | 657 | * buffer passing to the voice_thread (swcodec). Clips can be played |
675 | * can be played in chunks so the size is not that important */ | 658 | in chunks so the size is not that important */ |
676 | static unsigned char commit_buffer[2<<10]; | 659 | static unsigned char commit_buffer[2<<10]; |
677 | 660 | ||
678 | static void* commit_transfer(struct queue_entry *qe, size_t *size) | 661 | static void* commit_transfer(struct queue_entry *qe, size_t *size) |
679 | { | 662 | { |
680 | void *buf = NULL; /* shut up gcc */ | 663 | void *buf = NULL; /* shut up gcc */ |
681 | static unsigned char *bufpos = commit_buffer; | 664 | static unsigned char *bufpos = commit_buffer; |
682 | #if CONFIG_CODEC != SWCODEC | ||
683 | sent = MIN(qe->remaining, 0xFFFF); | ||
684 | #else | ||
685 | sent = qe->remaining; | 665 | sent = qe->remaining; |
686 | #endif | ||
687 | sent = MIN((size_t)sent, sizeof(commit_buffer)); | 666 | sent = MIN((size_t)sent, sizeof(commit_buffer)); |
688 | buf = buflib_get_data(&clip_ctx, qe->handle); | 667 | buf = buflib_get_data(&clip_ctx, qe->handle); |
689 | /* adjust buffer position to what has been played already */ | 668 | /* adjust buffer position to what has been played already */ |
@@ -706,13 +685,11 @@ static inline bool is_silence(struct queue_entry *qe) | |||
706 | static void mp3_callback(const void** start, size_t* size) | 685 | static void mp3_callback(const void** start, size_t* size) |
707 | { | 686 | { |
708 | struct queue_entry *qe = &queue[queue_read]; | 687 | struct queue_entry *qe = &queue[queue_read]; |
709 | #if CONFIG_CODEC == SWCODEC | ||
710 | /* voice_thread.c hints us how many of the buffer we provided it actually | 688 | /* voice_thread.c hints us how many of the buffer we provided it actually |
711 | * consumed. Because buffers have to be frame-aligned for speex | 689 | * consumed. Because buffers have to be frame-aligned for speex |
712 | * it might be less than what we presented */ | 690 | * it might be less than what we presented */ |
713 | if (*size) | 691 | if (*size) |
714 | sent = *size; | 692 | sent = *size; |
715 | #endif | ||
716 | qe->remaining -= sent; /* we completed this */ | 693 | qe->remaining -= sent; /* we completed this */ |
717 | 694 | ||
718 | if (qe->remaining > 0) /* current clip not finished? */ | 695 | if (qe->remaining > 0) /* current clip not finished? */ |
@@ -757,55 +734,7 @@ static void mp3_callback(const void** start, size_t* size) | |||
757 | /* stop the playback and the pending clips */ | 734 | /* stop the playback and the pending clips */ |
758 | void talk_force_shutup(void) | 735 | void talk_force_shutup(void) |
759 | { | 736 | { |
760 | /* Most of this is MAS only */ | 737 | /* Had nothing to do (was frame boundary or not our clip) */ |
761 | #if CONFIG_CODEC != SWCODEC | ||
762 | #ifdef SIMULATOR | ||
763 | return; | ||
764 | #endif | ||
765 | unsigned char* pos; | ||
766 | unsigned char* search; | ||
767 | unsigned char* end; | ||
768 | int len; | ||
769 | if (QUEUE_LEVEL == 0) /* has ended anyway */ | ||
770 | return; | ||
771 | |||
772 | /* search next frame boundary and continue up to there */ | ||
773 | pos = search = mp3_get_pos(); | ||
774 | end = buflib_get_data(&clip_ctx, queue[queue_read].handle); | ||
775 | len = queue[queue_read].length; | ||
776 | |||
777 | if (pos >= end && pos <= (end+len)) /* really our clip? */ | ||
778 | { /* (for strange reasons this isn't nesessarily the case) */ | ||
779 | /* find the next frame boundary */ | ||
780 | while (search < (end+len)) /* search the remaining data */ | ||
781 | { | ||
782 | if (*search++ != 0xFF) /* quick search for frame sync byte */ | ||
783 | continue; /* (this does the majority of the job) */ | ||
784 | |||
785 | /* look at the (bitswapped) rest of header candidate */ | ||
786 | if (search[0] == curr_hd[0] /* do the quicker checks first */ | ||
787 | && search[2] == curr_hd[2] | ||
788 | && (search[1] & 0x30) == (curr_hd[1] & 0x30)) /* sample rate */ | ||
789 | { | ||
790 | search--; /* back to the sync byte */ | ||
791 | break; /* From looking at it, this is our header. */ | ||
792 | } | ||
793 | } | ||
794 | |||
795 | if (search-pos) | ||
796 | { /* play old data until the frame end, to keep the MAS in sync */ | ||
797 | sent = search-pos; | ||
798 | |||
799 | queue_write = (queue_read + 1) & QUEUE_MASK; /* will be empty after next callback */ | ||
800 | queue[queue_read].length = sent; /* current one ends after this */ | ||
801 | |||
802 | thumbnail_buf_used = 0; | ||
803 | return; | ||
804 | } | ||
805 | } | ||
806 | #endif /* CONFIG_CODEC != SWCODEC */ | ||
807 | |||
808 | /* Either SWCODEC, or MAS had nothing to do (was frame boundary or not our clip) */ | ||
809 | mp3_play_stop(); | 738 | mp3_play_stop(); |
810 | talk_queue_lock(); | 739 | talk_queue_lock(); |
811 | queue_write = queue_read = 0; /* reset the queue */ | 740 | queue_write = queue_read = 0; /* reset the queue */ |
@@ -885,9 +814,7 @@ void talk_init(void) | |||
885 | 814 | ||
886 | if(!talk_initialized) | 815 | if(!talk_initialized) |
887 | { | 816 | { |
888 | #if CONFIG_CODEC == SWCODEC | ||
889 | mutex_init(&queue_mutex); | 817 | mutex_init(&queue_mutex); |
890 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
891 | mutex_init(&read_buffer_mutex); | 818 | mutex_init(&read_buffer_mutex); |
892 | } | 819 | } |
893 | 820 | ||
@@ -957,11 +884,9 @@ void talk_init(void) | |||
957 | 884 | ||
958 | load_voicefile_data(filehandle); | 885 | load_voicefile_data(filehandle); |
959 | 886 | ||
960 | #if CONFIG_CODEC == SWCODEC | ||
961 | /* Initialize the actual voice clip playback engine as well */ | 887 | /* Initialize the actual voice clip playback engine as well */ |
962 | if (talk_voice_required()) | 888 | if (talk_voice_required()) |
963 | voice_thread_init(); | 889 | voice_thread_init(); |
964 | #endif | ||
965 | 890 | ||
966 | out: | 891 | out: |
967 | close(filehandle); /* close again, this was just to detect presence */ | 892 | close(filehandle); /* close again, this was just to detect presence */ |
@@ -1062,9 +987,6 @@ static int _talk_file(const char* filename, | |||
1062 | int fd; | 987 | int fd; |
1063 | int size; | 988 | int size; |
1064 | int handle, oldest = -1; | 989 | int handle, oldest = -1; |
1065 | #if CONFIG_CODEC != SWCODEC | ||
1066 | struct mp3entry info; | ||
1067 | #endif | ||
1068 | 990 | ||
1069 | /* reload needed? */ | 991 | /* reload needed? */ |
1070 | if (talk_temp_disable_count > 0) | 992 | if (talk_temp_disable_count > 0) |
@@ -1080,13 +1002,6 @@ static int _talk_file(const char* filename, | |||
1080 | close(fd); | 1002 | close(fd); |
1081 | } | 1003 | } |
1082 | 1004 | ||
1083 | #if CONFIG_CODEC != SWCODEC | ||
1084 | if(mp3info(&info, filename)) /* use this to find real start */ | ||
1085 | { | ||
1086 | return 0; /* failed to open, or invalid */ | ||
1087 | } | ||
1088 | #endif | ||
1089 | |||
1090 | if (!enqueue) | 1005 | if (!enqueue) |
1091 | /* shutup now to free the thumbnail buffer */ | 1006 | /* shutup now to free the thumbnail buffer */ |
1092 | talk_shutup(); | 1007 | talk_shutup(); |
@@ -1098,10 +1013,6 @@ static int _talk_file(const char* filename, | |||
1098 | } | 1013 | } |
1099 | size = filesize(fd); | 1014 | size = filesize(fd); |
1100 | 1015 | ||
1101 | #if CONFIG_CODEC != SWCODEC | ||
1102 | size -= lseek(fd, info.first_frame_offset, SEEK_SET); /* behind ID data */ | ||
1103 | #endif | ||
1104 | |||
1105 | /* free clips from cache until this one succeeds to allocate */ | 1016 | /* free clips from cache until this one succeeds to allocate */ |
1106 | while ((handle = buflib_alloc(&clip_ctx, size)) < 0) | 1017 | while ((handle = buflib_alloc(&clip_ctx, size)) < 0) |
1107 | oldest = free_oldest_clip(); | 1018 | oldest = free_oldest_clip(); |
@@ -1116,10 +1027,6 @@ static int _talk_file(const char* filename, | |||
1116 | struct queue_entry clip; | 1027 | struct queue_entry clip; |
1117 | clip.handle = handle; | 1028 | clip.handle = handle; |
1118 | clip.length = clip.remaining = size; | 1029 | clip.length = clip.remaining = size; |
1119 | #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) | ||
1120 | /* bitswap doesnt yield() */ | ||
1121 | bitswap(buflib_get_data(&clip_ctx, handle), size); | ||
1122 | #endif | ||
1123 | if(prefix_ids) | 1030 | if(prefix_ids) |
1124 | /* prefix thumbnail by speaking these ids, but only now | 1031 | /* prefix thumbnail by speaking these ids, but only now |
1125 | that we know there's actually a thumbnail to be | 1032 | that we know there's actually a thumbnail to be |