summaryrefslogtreecommitdiff
path: root/apps/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/mpeg.c')
-rw-r--r--apps/mpeg.c89
1 files changed, 66 insertions, 23 deletions
diff --git a/apps/mpeg.c b/apps/mpeg.c
index b11445f947..a0182ad8d2 100644
--- a/apps/mpeg.c
+++ b/apps/mpeg.c
@@ -37,6 +37,7 @@
37#include "mp3data.h" 37#include "mp3data.h"
38#include "buffer.h" 38#include "buffer.h"
39#include "mp3_playback.h" 39#include "mp3_playback.h"
40#include "talk.h"
40#include "sound.h" 41#include "sound.h"
41#include "bitswap.h" 42#include "bitswap.h"
42#include "appevents.h" 43#include "appevents.h"
@@ -144,19 +145,19 @@ static unsigned int mpeg_errno;
144static bool playing = false; /* We are playing an MP3 stream */ 145static bool playing = false; /* We are playing an MP3 stream */
145static bool is_playing = false; /* We are (attempting to) playing MP3 files */ 146static bool is_playing = false; /* We are (attempting to) playing MP3 files */
146static bool paused; /* playback is paused */ 147static bool paused; /* playback is paused */
148static char* mpeg_audiobuf; /* the audio buffer */
149static long audiobuflen; /* length of the audio buffer */
147 150
148#ifdef SIMULATOR 151#ifdef SIMULATOR
149static char mpeg_stack[DEFAULT_STACK_SIZE]; 152static char mpeg_stack[DEFAULT_STACK_SIZE];
150static struct mp3entry taginfo; 153static struct mp3entry taginfo;
151
152#else /* !SIMULATOR */ 154#else /* !SIMULATOR */
153static struct event_queue mpeg_queue SHAREDBSS_ATTR; 155static struct event_queue mpeg_queue SHAREDBSS_ATTR;
154static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)]; 156static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
155 157
156static int audiobuflen;
157static int audiobuf_write; 158static int audiobuf_write;
158static int audiobuf_swapwrite; 159static int audiobuf_swapwrite;
159static int audiobuf_read; 160static long audiobuf_read;
160 161
161static int mpeg_file; 162static int mpeg_file;
162 163
@@ -490,6 +491,18 @@ unsigned long mpeg_get_last_header(void)
490#endif /* !SIMULATOR */ 491#endif /* !SIMULATOR */
491} 492}
492 493
494
495unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
496{
497 (void)talk_buf; /* always grab the voice buffer for now */
498
499 audio_hard_stop();
500 if (buffer_size) /* special case for talk_init() */
501 return buffer_get_buffer(buffer_size);
502 return NULL;
503}
504
505
493#ifndef SIMULATOR 506#ifndef SIMULATOR
494/* Send callback events to notify about removing old tracks. */ 507/* Send callback events to notify about removing old tracks. */
495static void generate_unbuffer_events(void) 508static void generate_unbuffer_events(void)
@@ -708,7 +721,7 @@ void rec_tick(void)
708 721
709 xor_b(0x08, &PADRH); /* Set PR inactive */ 722 xor_b(0x08, &PADRH); /* Set PR inactive */
710 723
711 audiobuf[audiobuf_write++] = data; 724 mpeg_audiobuf[audiobuf_write++] = data;
712 725
713 if (audiobuf_write >= audiobuflen) 726 if (audiobuf_write >= audiobuflen)
714 audiobuf_write = 0; 727 audiobuf_write = 0;
@@ -825,7 +838,7 @@ static void transfer_end(unsigned char** ppbuf, size_t* psize)
825 } 838 }
826 839
827 *psize = last_dma_chunk_size & 0xffff; 840 *psize = last_dma_chunk_size & 0xffff;
828 *ppbuf = audiobuf + audiobuf_read; 841 *ppbuf = mpeg_audiobuf + audiobuf_read;
829 track = get_trackdata(0); 842 track = get_trackdata(0);
830 if(track) 843 if(track)
831 track->id3.offset += last_dma_chunk_size; 844 track->id3.offset += last_dma_chunk_size;
@@ -1128,7 +1141,7 @@ static void start_playback_if_ready(void)
1128 playing = true; 1141 playing = true;
1129 1142
1130 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); 1143 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1131 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); 1144 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1132 dma_underrun = false; 1145 dma_underrun = false;
1133 1146
1134 if (!paused) 1147 if (!paused)
@@ -1173,7 +1186,7 @@ static bool swap_one_chunk(void)
1173 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite, 1186 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1174 amount_to_swap); 1187 amount_to_swap);
1175 1188
1176 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap); 1189 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1177 1190
1178 audiobuf_swapwrite += amount_to_swap; 1191 audiobuf_swapwrite += amount_to_swap;
1179 if(audiobuf_swapwrite >= audiobuflen) 1192 if(audiobuf_swapwrite >= audiobuflen)
@@ -1341,7 +1354,7 @@ static void mpeg_thread(void)
1341 track_change(); 1354 track_change();
1342 audiobuf_read = get_trackdata(0)->mempos; 1355 audiobuf_read = get_trackdata(0)->mempos;
1343 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); 1356 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1344 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); 1357 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1345 dma_underrun = false; 1358 dma_underrun = false;
1346 last_dma_tick = current_tick; 1359 last_dma_tick = current_tick;
1347 1360
@@ -1501,7 +1514,7 @@ static void mpeg_thread(void)
1501 /* resume will start at new position */ 1514 /* resume will start at new position */
1502 last_dma_chunk_size = 1515 last_dma_chunk_size =
1503 MIN(0x2000, get_unplayed_space_current_song()); 1516 MIN(0x2000, get_unplayed_space_current_song());
1504 mp3_play_data(audiobuf + audiobuf_read, 1517 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1505 last_dma_chunk_size, transfer_end); 1518 last_dma_chunk_size, transfer_end);
1506 dma_underrun = false; 1519 dma_underrun = false;
1507 } 1520 }
@@ -1632,7 +1645,7 @@ static void mpeg_thread(void)
1632 { 1645 {
1633 DEBUGF("R\n"); 1646 DEBUGF("R\n");
1634 t1 = current_tick; 1647 t1 = current_tick;
1635 len = read(mpeg_file, audiobuf + audiobuf_write, 1648 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1636 amount_to_read); 1649 amount_to_read);
1637 if(len > 0) 1650 if(len > 0)
1638 { 1651 {
@@ -1659,7 +1672,7 @@ static void mpeg_thread(void)
1659 if(tagptr >= audiobuflen) 1672 if(tagptr >= audiobuflen)
1660 tagptr -= audiobuflen; 1673 tagptr -= audiobuflen;
1661 1674
1662 if(audiobuf[tagptr] != tag[i]) 1675 if(mpeg_audiobuf[tagptr] != tag[i])
1663 { 1676 {
1664 taglen = 0; 1677 taglen = 0;
1665 break; 1678 break;
@@ -1773,19 +1786,20 @@ static void mpeg_thread(void)
1773 startpos = prerecord_buffer[startpos].mempos; 1786 startpos = prerecord_buffer[startpos].mempos;
1774 1787
1775 DEBUGF("Start looking at address %x (%x)\n", 1788 DEBUGF("Start looking at address %x (%x)\n",
1776 audiobuf+startpos, startpos); 1789 mpeg_audiobuf+startpos, startpos);
1777 1790
1778 saved_header = mpeg_get_last_header(); 1791 saved_header = mpeg_get_last_header();
1779 1792
1780 mem_find_next_frame(startpos, &offset, 1800, 1793 mem_find_next_frame(startpos, &offset, 1800,
1781 saved_header); 1794 saved_header, mpeg_audiobuf,
1795 audiobuflen);
1782 1796
1783 audiobuf_read = startpos + offset; 1797 audiobuf_read = startpos + offset;
1784 if(audiobuf_read >= audiobuflen) 1798 if(audiobuf_read >= audiobuflen)
1785 audiobuf_read -= audiobuflen; 1799 audiobuf_read -= audiobuflen;
1786 1800
1787 DEBUGF("New audiobuf_read address: %x (%x)\n", 1801 DEBUGF("New audiobuf_read address: %x (%x)\n",
1788 audiobuf+audiobuf_read, audiobuf_read); 1802 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1789 1803
1790 level = disable_irq_save(); 1804 level = disable_irq_save();
1791 num_rec_bytes = get_unsaved_space(); 1805 num_rec_bytes = get_unsaved_space();
@@ -1894,7 +1908,8 @@ static void mpeg_thread(void)
1894 save_endpos += audiobuflen; 1908 save_endpos += audiobuflen;
1895 1909
1896 rc = mem_find_next_frame(save_endpos, &offset, 1800, 1910 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1897 saved_header); 1911 saved_header, mpeg_audiobuf,
1912 audiobuflen);
1898 if (!rc) /* No header found, save whole buffer */ 1913 if (!rc) /* No header found, save whole buffer */
1899 offset = 1800; 1914 offset = 1800;
1900 1915
@@ -1936,7 +1951,7 @@ static void mpeg_thread(void)
1936#elif MEMORYSIZE == 8 1951#elif MEMORYSIZE == 8
1937 amount_to_save = MIN(0x100000, amount_to_save); 1952 amount_to_save = MIN(0x100000, amount_to_save);
1938#endif 1953#endif
1939 rc = write(mpeg_file, audiobuf + audiobuf_read, 1954 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
1940 amount_to_save); 1955 amount_to_save);
1941 if (rc < 0) 1956 if (rc < 0)
1942 { 1957 {
@@ -2256,21 +2271,21 @@ static void prepend_header(void)
2256 if(audiobuf_read < 0) 2271 if(audiobuf_read < 0)
2257 { 2272 {
2258 /* Clear the bottom half */ 2273 /* Clear the bottom half */
2259 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE); 2274 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2260 2275
2261 /* And the top half */ 2276 /* And the top half */
2262 audiobuf_read += audiobuflen; 2277 audiobuf_read += audiobuflen;
2263 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read); 2278 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2264 } 2279 }
2265 else 2280 else
2266 { 2281 {
2267 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE); 2282 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2268 } 2283 }
2269 /* Copy the empty ID3 header */ 2284 /* Copy the empty ID3 header */
2270 startpos = audiobuf_read; 2285 startpos = audiobuf_read;
2271 for(i = 0; i < sizeof(empty_id3_header); i++) 2286 for(i = 0; i < sizeof(empty_id3_header); i++)
2272 { 2287 {
2273 audiobuf[startpos++] = empty_id3_header[i]; 2288 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2274 if(startpos == audiobuflen) 2289 if(startpos == audiobuflen)
2275 startpos = 0; 2290 startpos = 0;
2276 } 2291 }
@@ -2297,7 +2312,8 @@ static void update_header(void)
2297 /* saved_header is saved right before stopping the MAS */ 2312 /* saved_header is saved right before stopping the MAS */
2298 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, 2313 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2299 frames, last_rec_time * (1000/HZ), 2314 frames, last_rec_time * (1000/HZ),
2300 saved_header, NULL, false); 2315 saved_header, NULL, false,
2316 mpeg_audiobuf, audiobuflen);
2301 2317
2302 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); 2318 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2303 write(fd, xing_buffer, framelen); 2319 write(fd, xing_buffer, framelen);
@@ -2645,8 +2661,22 @@ void audio_set_recording_options(struct audio_recording_options *options)
2645#endif /* SIMULATOR */ 2661#endif /* SIMULATOR */
2646#endif /* CONFIG_CODEC == MAS3587F */ 2662#endif /* CONFIG_CODEC == MAS3587F */
2647 2663
2664static void audio_reset_buffer(void)
2665{
2666 size_t bufsize; /* dont break strict-aliasing */
2667 talk_buffer_steal(); /* will use the mp3 buffer */
2668
2669 /* release buffer on behalf of any audio_get_buffer() caller,
2670 * non-fatal if there was none */
2671 buffer_release_buffer(0);
2672 /* re-aquire */
2673 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2674 audiobuflen = bufsize;
2675}
2676
2648void audio_play(long offset) 2677void audio_play(long offset)
2649{ 2678{
2679 audio_reset_buffer();
2650#ifdef SIMULATOR 2680#ifdef SIMULATOR
2651 char name_buf[MAX_PATH+1]; 2681 char name_buf[MAX_PATH+1];
2652 const char* trackname; 2682 const char* trackname;
@@ -2676,7 +2706,6 @@ void audio_play(long offset)
2676 } while(1); 2706 } while(1);
2677#else /* !SIMULATOR */ 2707#else /* !SIMULATOR */
2678 is_playing = true; 2708 is_playing = true;
2679
2680 queue_post(&mpeg_queue, MPEG_PLAY, offset); 2709 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2681#endif /* !SIMULATOR */ 2710#endif /* !SIMULATOR */
2682 2711
@@ -2700,6 +2729,8 @@ void audio_stop(void)
2700 is_playing = false; 2729 is_playing = false;
2701 playing = false; 2730 playing = false;
2702#endif /* SIMULATOR */ 2731#endif /* SIMULATOR */
2732 /* give voice our entire buffer */
2733 talkbuf_init(mpeg_audiobuf);
2703} 2734}
2704 2735
2705/* dummy */ 2736/* dummy */
@@ -2708,6 +2739,14 @@ void audio_stop_recording(void)
2708 audio_stop(); 2739 audio_stop();
2709} 2740}
2710 2741
2742void audio_hard_stop(void)
2743{
2744 audio_stop();
2745 /* tell voice we obtain the buffer before freeing */
2746 talk_buffer_steal();
2747 buffer_release_buffer(0);
2748}
2749
2711void audio_pause(void) 2750void audio_pause(void)
2712{ 2751{
2713#ifndef SIMULATOR 2752#ifndef SIMULATOR
@@ -2864,8 +2903,12 @@ void audio_init(void)
2864 if (global_settings.cuesheet) 2903 if (global_settings.cuesheet)
2865 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet)); 2904 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2866 2905
2906 size_t bufsize; /* don't break strict-aliasing */
2907 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2908 audiobuflen = bufsize;
2909 /* give voice buffer until we start to play */
2910 talkbuf_init(mpeg_audiobuf);
2867#ifndef SIMULATOR 2911#ifndef SIMULATOR
2868 audiobuflen = audiobufend - audiobuf;
2869 queue_init(&mpeg_queue, true); 2912 queue_init(&mpeg_queue, true);
2870#endif /* !SIMULATOR */ 2913#endif /* !SIMULATOR */
2871 create_thread(mpeg_thread, mpeg_stack, 2914 create_thread(mpeg_thread, mpeg_stack,