summaryrefslogtreecommitdiff
path: root/apps/mpeg.c
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-07-15 19:40:55 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-07-24 21:20:13 +0000
commit092c340a2062fa98b7387fc5fd63578ddae7d0b6 (patch)
tree98ec96946eeb2ae709cb0528cc6998e21bb9b290 /apps/mpeg.c
parent17f7cc92c258bc456a27c3e7c5a19c9409851879 (diff)
downloadrockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.tar.gz
rockbox-092c340a2062fa98b7387fc5fd63578ddae7d0b6.zip
[1/4] Remove SH support and all archos targets
This removes all code specific to SH targets Change-Id: I7980523785d2596e65c06430f4638eec74a06061
Diffstat (limited to 'apps/mpeg.c')
-rw-r--r--apps/mpeg.c1079
1 files changed, 0 insertions, 1079 deletions
diff --git a/apps/mpeg.c b/apps/mpeg.c
index d3e0e5c137..e04c227cb1 100644
--- a/apps/mpeg.c
+++ b/apps/mpeg.c
@@ -46,7 +46,6 @@
46#include "settings.h" 46#include "settings.h"
47#ifndef SIMULATOR 47#ifndef SIMULATOR
48#include "i2c.h" 48#include "i2c.h"
49#include "mas35xx.h"
50#include "system.h" 49#include "system.h"
51#include "usb.h" 50#include "usb.h"
52#include "file.h" 51#include "file.h"
@@ -81,14 +80,6 @@
81extern unsigned long mas_version_code; 80extern unsigned long mas_version_code;
82#endif 81#endif
83 82
84#if CONFIG_CODEC == MAS3587F
85extern enum /* from mp3_playback.c */
86{
87 MPEG_DECODER,
88 MPEG_ENCODER
89} mpeg_mode;
90#endif /* CONFIG_CODEC == MAS3587F */
91
92#define MPEG_PLAY 1 83#define MPEG_PLAY 1
93#define MPEG_STOP 2 84#define MPEG_STOP 2
94#define MPEG_PAUSE 3 85#define MPEG_PAUSE 3
@@ -184,61 +175,6 @@ struct audio_resume_info
184 unsigned long offset; 175 unsigned long offset;
185}; 176};
186 177
187#if CONFIG_CODEC == MAS3587F
188static char recording_filename[MAX_PATH]; /* argument to thread */
189static char delayed_filename[MAX_PATH]; /* internal copy of above */
190
191static char xing_buffer[MAX_XING_HEADER_SIZE];
192
193static bool init_recording_done;
194static bool init_playback_done;
195static bool prerecording; /* True if prerecording is enabled */
196static bool is_prerecording; /* True if we are prerecording */
197static bool is_recording; /* We are recording */
198
199static enum {
200 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
201 BUFFER_FULL,
202 NEW_FILE,
203 STOP_RECORDING
204} saving_status;
205
206static int rec_frequency_index; /* For create_xing_header() calls */
207static int rec_version_index; /* For create_xing_header() calls */
208
209struct prerecord_info {
210 int mempos;
211 unsigned long framecount;
212};
213
214static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
215static int prerecord_index; /* Current index in the prerecord buffer */
216static int prerecording_max_seconds; /* Max number of seconds to store */
217static int prerecord_count; /* Number of seconds in the prerecord buffer */
218static int prerecord_timeout; /* The tick count of the next prerecord data
219 store */
220
221static unsigned long record_start_time; /* Value of current_tick when recording
222 was started */
223static unsigned long pause_start_time; /* Value of current_tick when pause was
224 started */
225static unsigned long last_rec_time;
226static unsigned long num_rec_bytes;
227static unsigned long last_rec_bytes;
228static unsigned long frame_count_start;
229static unsigned long frame_count_end;
230static unsigned long saved_header = 0;
231
232/* Shadow MAS registers */
233unsigned long shadow_encoder_control = 0;
234#endif /* CONFIG_CODEC == MAS3587F */
235
236#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
237unsigned long shadow_io_control_main = 0;
238unsigned long shadow_soft_mute = 0;
239unsigned shadow_codec_reg0;
240#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
241
242#ifdef HAVE_RECORDING 178#ifdef HAVE_RECORDING
243static const unsigned char empty_id3_header[] = 179static const unsigned char empty_id3_header[] =
244{ 180{
@@ -253,18 +189,6 @@ static int get_playable_space(void);
253static int get_unswapped_space(void); 189static int get_unswapped_space(void);
254#endif /* !SIMULATOR */ 190#endif /* !SIMULATOR */
255 191
256#if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
257static void init_recording(void);
258static void prepend_header(void);
259static void update_header(void);
260static void start_prerecording(void);
261static void start_recording(void);
262static void stop_recording(void);
263static int get_unsaved_space(void);
264static void pause_recording(void);
265static void resume_recording(void);
266#endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
267
268static void audio_reset_buffer_noalloc(void* buf, size_t bufsize); 192static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
269static void audio_reset_buffer(void); 193static void audio_reset_buffer(void);
270 194
@@ -540,12 +464,6 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s
540 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); 464 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
541 ssize_t size = (ssize_t)old_size - wanted_size; 465 ssize_t size = (ssize_t)old_size - wanted_size;
542 466
543#if !defined(SIMULATOR) && (CONFIG_CODEC == MAS3587F)
544 /* FIXME: Cannot give the buffer during recording yet */
545 if (is_recording)
546 return BUFLIB_CB_CANNOT_SHRINK;
547#endif
548
549 /* keep at least 256K for the buffering */ 467 /* keep at least 256K for the buffering */
550 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE) 468 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE)
551 { 469 {
@@ -677,9 +595,6 @@ void audio_get_debugdata(struct audio_debug *dbgdata)
677 595
678 dbgdata->last_dma_chunk_size = last_dma_chunk_size; 596 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
679 597
680#if CONFIG_CPU == SH7034
681 dbgdata->dma_on = (SCR0 & 0x80) != 0;
682#endif
683 dbgdata->playing = playing; 598 dbgdata->playing = playing;
684 dbgdata->play_pending = play_pending; 599 dbgdata->play_pending = play_pending;
685 dbgdata->is_playing = is_playing; 600 dbgdata->is_playing = is_playing;
@@ -758,108 +673,6 @@ static int get_unswapped_space(void)
758 return space; 673 return space;
759} 674}
760 675
761#if CONFIG_CODEC == MAS3587F
762static int get_unsaved_space(void)
763{
764 int space = audiobuf_write - audiobuf_read;
765 if (space < 0)
766 space += audiobuflen;
767 return space;
768}
769
770static void drain_dma_buffer(void)
771{
772 while (PBDRH & 0x40)
773 {
774 xor_b(0x08, &PADRH);
775
776 while (PBDRH & 0x80);
777
778 xor_b(0x08, &PADRH);
779
780 while (!(PBDRH & 0x80));
781 }
782}
783
784#ifdef DEBUG
785static long timing_info_index = 0;
786static long timing_info[1024];
787#endif /* DEBUG */
788
789void rec_tick (void) __attribute__ ((section (".icode")));
790void rec_tick(void)
791{
792 int i;
793 int delay;
794 char data;
795
796 if(is_recording && (PBDRH & 0x40))
797 {
798#ifdef DEBUG
799 timing_info[timing_info_index++] = current_tick;
800 TCNT2 = 0;
801#endif /* DEBUG */
802 /* Note: Although this loop is run in interrupt context, further
803 * optimisation will do no good. The MAS would then deliver bad
804 * frames occasionally, as observed in extended experiments. */
805 i = 0;
806 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
807 {
808 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
809
810 delay = 100;
811 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
812 {
813 if (--delay <= 0) /* Bail out if we have to wait too long */
814 { /* i.e. the MAS doesn't want to talk to us */
815 xor_b(0x08, &PADRH); /* Set PR inactive */
816 goto transfer_end; /* and get out of here */
817 }
818 }
819
820 data = *(unsigned char *)0x04000000; /* read data byte */
821
822 xor_b(0x08, &PADRH); /* Set PR inactive */
823
824 mpeg_audiobuf[audiobuf_write++] = data;
825
826 if (audiobuf_write >= audiobuflen)
827 audiobuf_write = 0;
828
829 i++;
830 }
831 transfer_end:
832
833#ifdef DEBUG
834 timing_info[timing_info_index++] = TCNT2 + (i << 16);
835 timing_info_index &= 0x3ff;
836#endif /* DEBUG */
837
838 num_rec_bytes += i;
839
840 if(is_prerecording)
841 {
842 if(TIME_AFTER(current_tick, prerecord_timeout))
843 {
844 prerecord_timeout = current_tick + HZ;
845 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
846 }
847 }
848 else
849 {
850 /* Signal to save the data if we are running out of buffer
851 space */
852 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
853 && saving_status == NOT_SAVING)
854 {
855 saving_status = BUFFER_FULL;
856 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
857 }
858 }
859 }
860}
861#endif /* CONFIG_CODEC == MAS3587F */
862
863void playback_tick(void) 676void playback_tick(void)
864{ 677{
865 struct trackdata *ptd = get_trackdata(0); 678 struct trackdata *ptd = get_trackdata(0);
@@ -1158,11 +971,6 @@ static void track_change(void)
1158{ 971{
1159 DEBUGF("Track change\n"); 972 DEBUGF("Track change\n");
1160 973
1161#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1162 /* Reset the AVC */
1163 sound_set_avc(-1);
1164#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1165
1166 if (num_tracks_in_memory() > 0) 974 if (num_tracks_in_memory() > 0)
1167 { 975 {
1168 remove_current_tag(); 976 remove_current_tag();
@@ -1293,13 +1101,6 @@ static void mpeg_thread(void)
1293 int amount_to_read; 1101 int amount_to_read;
1294 int t1, t2; 1102 int t1, t2;
1295 unsigned long start_elapsed, start_offset; 1103 unsigned long start_elapsed, start_offset;
1296#if CONFIG_CODEC == MAS3587F
1297 int amount_to_save;
1298 int save_endpos = 0;
1299 int rc;
1300 int level;
1301 long offset;
1302#endif /* CONFIG_CODEC == MAS3587F */
1303 1104
1304 is_playing = false; 1105 is_playing = false;
1305 play_pending = false; 1106 play_pending = false;
@@ -1308,10 +1109,6 @@ static void mpeg_thread(void)
1308 1109
1309 while(1) 1110 while(1)
1310 { 1111 {
1311#if CONFIG_CODEC == MAS3587F
1312 if(mpeg_mode == MPEG_DECODER)
1313 {
1314#endif /* CONFIG_CODEC == MAS3587F */
1315 yield(); 1112 yield();
1316 1113
1317 /* Swap if necessary, and don't block on the queue_wait() */ 1114 /* Swap if necessary, and don't block on the queue_wait() */
@@ -1836,321 +1633,11 @@ static void mpeg_thread(void)
1836 break; 1633 break;
1837#endif /* !USB_NONE */ 1634#endif /* !USB_NONE */
1838 1635
1839#if CONFIG_CODEC == MAS3587F
1840 case MPEG_INIT_RECORDING:
1841 init_recording();
1842 init_recording_done = true;
1843 break;
1844#endif /* CONFIG_CODEC == MAS3587F */
1845
1846 case SYS_TIMEOUT: 1636 case SYS_TIMEOUT:
1847 if (playing) 1637 if (playing)
1848 playlist_update_resume_info(audio_current_track()); 1638 playlist_update_resume_info(audio_current_track());
1849 break; 1639 break;
1850 } 1640 }
1851#if CONFIG_CODEC == MAS3587F
1852 }
1853 else
1854 {
1855 queue_wait(&mpeg_queue, &ev);
1856 switch(ev.id)
1857 {
1858 case MPEG_RECORD:
1859 if (is_prerecording)
1860 {
1861 int startpos;
1862
1863 /* Go back prerecord_count seconds in the buffer */
1864 startpos = prerecord_index - prerecord_count;
1865 if(startpos < 0)
1866 startpos += prerecording_max_seconds;
1867
1868 /* Read the position data from the prerecord buffer */
1869 frame_count_start = prerecord_buffer[startpos].framecount;
1870 startpos = prerecord_buffer[startpos].mempos;
1871
1872 DEBUGF("Start looking at address %x (%x)\n",
1873 mpeg_audiobuf+startpos, startpos);
1874
1875 saved_header = mpeg_get_last_header();
1876
1877 mem_find_next_frame(startpos, &offset, 1800,
1878 saved_header, mpeg_audiobuf,
1879 audiobuflen);
1880
1881 audiobuf_read = startpos + offset;
1882 if(audiobuf_read >= audiobuflen)
1883 audiobuf_read -= audiobuflen;
1884
1885 DEBUGF("New audiobuf_read address: %x (%x)\n",
1886 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1887
1888 level = disable_irq_save();
1889 num_rec_bytes = get_unsaved_space();
1890 restore_irq(level);
1891 }
1892 else
1893 {
1894 frame_count_start = 0;
1895 num_rec_bytes = 0;
1896 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1897 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1898 }
1899
1900 prepend_header();
1901 DEBUGF("Recording...\n");
1902 start_recording();
1903
1904 /* Wait until at least one frame is encoded and get the
1905 frame header, for later use by the Xing header
1906 generation */
1907 sleep(HZ/5);
1908 saved_header = mpeg_get_last_header();
1909
1910 /* delayed until buffer is saved, don't open yet */
1911 strcpy(delayed_filename, recording_filename);
1912 mpeg_file = -1;
1913
1914 break;
1915
1916 case MPEG_STOP:
1917 DEBUGF("MPEG_STOP\n");
1918
1919 stop_recording();
1920
1921 /* Save the remaining data in the buffer */
1922 save_endpos = audiobuf_write;
1923 saving_status = STOP_RECORDING;
1924 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1925 break;
1926
1927 case MPEG_STOP_DONE:
1928 DEBUGF("MPEG_STOP_DONE\n");
1929
1930 if (mpeg_file >= 0)
1931 close(mpeg_file);
1932 mpeg_file = -1;
1933
1934 update_header();
1935#ifdef DEBUG1
1936 {
1937 int i;
1938 for(i = 0;i < 512;i++)
1939 {
1940 DEBUGF("%d - %d us (%d bytes)\n",
1941 timing_info[i*2],
1942 (timing_info[i*2+1] & 0xffff) *
1943 10000 / 13824,
1944 timing_info[i*2+1] >> 16);
1945 }
1946 }
1947#endif /* DEBUG1 */
1948
1949 if (prerecording)
1950 {
1951 start_prerecording();
1952 }
1953 mpeg_stop_done = true;
1954 break;
1955
1956 case MPEG_NEW_FILE:
1957 /* Bail out when a more important save is happening */
1958 if (saving_status > NEW_FILE)
1959 break;
1960
1961 /* Make sure we have at least one complete frame
1962 in the buffer. If we haven't recorded a single
1963 frame within 200ms, the MAS is probably not recording
1964 anything, and we bail out. */
1965 amount_to_save = get_unsaved_space();
1966 if (amount_to_save < 1800)
1967 {
1968 sleep(HZ/5);
1969 amount_to_save = get_unsaved_space();
1970 }
1971
1972 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1973 &frame_count_end, 1);
1974
1975 last_rec_time = current_tick - record_start_time;
1976 record_start_time = current_tick;
1977 if (paused)
1978 pause_start_time = record_start_time;
1979
1980 /* capture all values at one point */
1981 level = disable_irq_save();
1982 save_endpos = audiobuf_write;
1983 last_rec_bytes = num_rec_bytes;
1984 num_rec_bytes = 0;
1985 restore_irq(level);
1986
1987 if (amount_to_save >= 1800)
1988 {
1989 /* Now find a frame boundary to split at */
1990 save_endpos -= 1800;
1991 if (save_endpos < 0)
1992 save_endpos += audiobuflen;
1993
1994 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1995 saved_header, mpeg_audiobuf,
1996 audiobuflen);
1997 if (!rc) /* No header found, save whole buffer */
1998 offset = 1800;
1999
2000 save_endpos += offset;
2001 if (save_endpos >= audiobuflen)
2002 save_endpos -= audiobuflen;
2003
2004 last_rec_bytes += offset - 1800;
2005 level = disable_irq_save();
2006 num_rec_bytes += 1800 - offset;
2007 restore_irq(level);
2008 }
2009
2010 saving_status = NEW_FILE;
2011 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2012 break;
2013
2014 case MPEG_SAVE_DATA:
2015 if (saving_status == BUFFER_FULL)
2016 save_endpos = audiobuf_write;
2017
2018 if (mpeg_file < 0) /* delayed file open */
2019 {
2020 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2021
2022 if (mpeg_file < 0)
2023 panicf("recfile: %d", mpeg_file);
2024 }
2025
2026 amount_to_save = save_endpos - audiobuf_read;
2027 if (amount_to_save < 0)
2028 amount_to_save += audiobuflen;
2029
2030 amount_to_save = MIN(amount_to_save,
2031 audiobuflen - audiobuf_read);
2032#if (CONFIG_STORAGE & STORAGE_MMC)
2033 /* MMC is slow, so don't save too large chunks at once */
2034 amount_to_save = MIN(0x40000, amount_to_save);
2035#elif MEMORYSIZE == 8
2036 amount_to_save = MIN(0x100000, amount_to_save);
2037#endif
2038 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2039 amount_to_save);
2040 if (rc < 0)
2041 {
2042 if (errno == ENOSPC)
2043 {
2044 mpeg_errno = AUDIOERR_DISK_FULL;
2045 stop_recording();
2046 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2047 /* will close the file */
2048 break;
2049 }
2050 else
2051 panicf("rec wrt: %d", rc);
2052 }
2053
2054 audiobuf_read += amount_to_save;
2055 if (audiobuf_read >= audiobuflen)
2056 audiobuf_read = 0;
2057
2058 if (audiobuf_read == save_endpos) /* all saved */
2059 {
2060 switch (saving_status)
2061 {
2062 case BUFFER_FULL:
2063 rc = fsync(mpeg_file);
2064 if (rc < 0)
2065 panicf("rec fls: %d", rc);
2066 storage_sleep();
2067 break;
2068
2069 case NEW_FILE:
2070 /* Close the current file */
2071 rc = close(mpeg_file);
2072 if (rc < 0)
2073 panicf("rec cls: %d", rc);
2074 mpeg_file = -1;
2075 update_header();
2076 storage_sleep();
2077
2078 /* copy new filename */
2079 strcpy(delayed_filename, recording_filename);
2080 prepend_header();
2081 frame_count_start = frame_count_end;
2082 break;
2083
2084 case STOP_RECORDING:
2085 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2086 /* will close the file */
2087 break;
2088
2089 default:
2090 break;
2091 }
2092 saving_status = NOT_SAVING;
2093 }
2094 else /* tell ourselves to save the next chunk */
2095 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2096
2097 break;
2098
2099 case MPEG_PRERECORDING_TICK:
2100 if(!is_prerecording)
2101 break;
2102
2103 /* Store the write pointer every second */
2104 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2105 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2106 &prerecord_buffer[prerecord_index].framecount, 1);
2107
2108 /* Wrap if necessary */
2109 if(++prerecord_index == prerecording_max_seconds)
2110 prerecord_index = 0;
2111
2112 /* Update the number of seconds recorded */
2113 if(prerecord_count < prerecording_max_seconds)
2114 prerecord_count++;
2115 break;
2116
2117 case MPEG_INIT_PLAYBACK:
2118 /* Stop the prerecording */
2119 stop_recording();
2120 reset_mp3_buffer();
2121 mp3_play_init();
2122 init_playback_done = true;
2123 break;
2124
2125 case MPEG_PAUSE_RECORDING:
2126 pause_recording();
2127 break;
2128
2129 case MPEG_RESUME_RECORDING:
2130 resume_recording();
2131 break;
2132
2133 case SYS_USB_CONNECTED:
2134 /* We can safely go to USB mode if no recording
2135 is taking place */
2136 if((!is_recording || is_prerecording) && mpeg_stop_done)
2137 {
2138 /* Even if we aren't recording, we still call this
2139 function, to put the MAS in monitoring mode,
2140 to save power. */
2141 stop_recording();
2142
2143 /* Tell the USB thread that we are safe */
2144 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2145 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2146
2147 /* Wait until the USB cable is extracted again */
2148 usb_wait_for_disconnect(&mpeg_queue);
2149 }
2150 break;
2151 }
2152 }
2153#endif /* CONFIG_CODEC == MAS3587F */
2154 } 1641 }
2155} 1642}
2156#endif /* !SIMULATOR */ 1643#endif /* !SIMULATOR */
@@ -2195,557 +1682,6 @@ struct mp3entry* audio_next_track(void)
2195#endif /* !SIMULATOR */ 1682#endif /* !SIMULATOR */
2196} 1683}
2197 1684
2198#if CONFIG_CODEC == MAS3587F
2199#ifndef SIMULATOR
2200void audio_init_playback(void)
2201{
2202 init_playback_done = false;
2203 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2204
2205 while(!init_playback_done)
2206 sleep(1);
2207}
2208
2209
2210/****************************************************************************
2211 * Recording functions
2212 ***************************************************************************/
2213void audio_init_recording(void)
2214{
2215 init_recording_done = false;
2216 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2217
2218 while(!init_recording_done)
2219 sleep(1);
2220}
2221
2222static void init_recording(void)
2223{
2224 unsigned long val;
2225 int rc;
2226
2227 /* Disable IRQ6 */
2228 IPRB &= 0xff0f;
2229
2230 stop_playing();
2231 is_playing = false;
2232 paused = false;
2233
2234 /* Init the recording variables */
2235 is_recording = false;
2236 is_prerecording = false;
2237
2238 /* Have to grab the audio buffer in case voice had it */
2239 audio_reset_buffer();
2240
2241 mpeg_stop_done = true;
2242
2243 mas_reset();
2244
2245 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2246 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2247 if(rc < 0)
2248 panicf("mas_ctrl_w: %d", rc);
2249
2250 /* Stop the current application */
2251 val = 0;
2252 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2253 do
2254 {
2255 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2256 } while(val);
2257
2258 /* Perform black magic as described by the data sheet */
2259 if((mas_version_code & 0x0fff) == 0x0102)
2260 {
2261 DEBUGF("Performing MAS black magic for B2 version\n");
2262 mas_writereg(0xa3, 0x98);
2263 mas_writereg(0x94, 0xfffff);
2264 val = 0;
2265 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2266 mas_writereg(0xa3, 0x90);
2267 }
2268
2269 /* Enable A/D Converters */
2270 shadow_codec_reg0 = 0xcccd;
2271 mas_codec_writereg(0x0, shadow_codec_reg0);
2272
2273 /* Copy left channel to right (mono mode) */
2274 mas_codec_writereg(8, 0x8000);
2275
2276 /* ADC scale 0%, DSP scale 100%
2277 We use the DSP output for monitoring, because it works with all
2278 sources including S/PDIF */
2279 mas_codec_writereg(6, 0x0000);
2280 mas_codec_writereg(7, 0x4000);
2281
2282 /* No mute */
2283 shadow_soft_mute = 0;
2284 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2285
2286#ifdef HAVE_SPDIF_OUT
2287 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2288#else
2289 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2290#endif
2291 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2292
2293 /* Set Demand mode, monitoring OFF and validate all settings */
2294 shadow_io_control_main = 0x125;
2295 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2296
2297 /* Start the encoder application */
2298 val = 0x40;
2299 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2300 do
2301 {
2302 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2303 } while(!(val & 0x40));
2304
2305 /* We have started the recording application with monitoring OFF.
2306 This is because we want to record at least one frame to fill the DMA
2307 buffer, because the silly MAS will not negate EOD until at least one
2308 DMA transfer has taken place.
2309 Now let's wait for some data to be encoded. */
2310 sleep(HZ/5);
2311
2312 /* Now set it to Monitoring mode as default, saves power */
2313 shadow_io_control_main = 0x525;
2314 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2315
2316 /* Wait until the DSP has accepted the settings */
2317 do
2318 {
2319 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2320 } while(val & 1);
2321
2322 drain_dma_buffer();
2323 mpeg_mode = MPEG_ENCODER;
2324
2325 DEBUGF("MAS Recording application started\n");
2326
2327 /* At this point, all settings are the reset MAS defaults, next thing is to
2328 call mpeg_set_recording_options(). */
2329}
2330
2331void audio_record(const char *filename)
2332{
2333 mpeg_errno = 0;
2334
2335 strlcpy(recording_filename, filename, MAX_PATH);
2336
2337 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2338}
2339
2340void audio_pause_recording(void)
2341{
2342 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2343}
2344
2345void audio_resume_recording(void)
2346{
2347 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2348}
2349
2350static void prepend_header(void)
2351{
2352 int startpos;
2353 unsigned i;
2354
2355 /* Make room for header */
2356 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2357 if(audiobuf_read < 0)
2358 {
2359 /* Clear the bottom half */
2360 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2361
2362 /* And the top half */
2363 audiobuf_read += audiobuflen;
2364 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2365 }
2366 else
2367 {
2368 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2369 }
2370 /* Copy the empty ID3 header */
2371 startpos = audiobuf_read;
2372 for(i = 0; i < sizeof(empty_id3_header); i++)
2373 {
2374 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2375 if(startpos == audiobuflen)
2376 startpos = 0;
2377 }
2378}
2379
2380static void update_header(void)
2381{
2382 int fd, framelen;
2383 unsigned long frames;
2384
2385 if (last_rec_bytes > 0)
2386 {
2387 /* Create the Xing header */
2388 fd = open(delayed_filename, O_RDWR);
2389 if (fd < 0)
2390 panicf("rec upd: %d (%s)", fd, recording_filename);
2391
2392 frames = frame_count_end - frame_count_start;
2393 /* If the number of recorded frames has reached 0x7ffff,
2394 we can no longer trust it */
2395 if (frame_count_end == 0x7ffff)
2396 frames = 0;
2397
2398 /* saved_header is saved right before stopping the MAS */
2399 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2400 frames, last_rec_time * (1000/HZ),
2401 saved_header, NULL, false,
2402 mpeg_audiobuf, audiobuflen);
2403
2404 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2405 write(fd, xing_buffer, framelen);
2406 close(fd);
2407 }
2408}
2409
2410static void start_prerecording(void)
2411{
2412 unsigned long val;
2413
2414 DEBUGF("Starting prerecording\n");
2415
2416 prerecord_index = 0;
2417 prerecord_count = 0;
2418 prerecord_timeout = current_tick + HZ;
2419 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2420 reset_mp3_buffer();
2421
2422 is_prerecording = true;
2423
2424 /* Stop monitoring and start the encoder */
2425 shadow_io_control_main &= ~(1 << 10);
2426 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2427 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2428
2429 /* Wait until the DSP has accepted the settings */
2430 do
2431 {
2432 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2433 } while(val & 1);
2434
2435 is_recording = true;
2436 saving_status = NOT_SAVING;
2437
2438 demand_irq_enable(true);
2439}
2440
2441static void start_recording(void)
2442{
2443 unsigned long val;
2444
2445 if(is_prerecording)
2446 {
2447 /* This will make the IRQ handler start recording
2448 for real, i.e send MPEG_SAVE_DATA messages when
2449 the buffer is full */
2450 is_prerecording = false;
2451 }
2452 else
2453 {
2454 /* If prerecording is off, we need to stop the monitoring
2455 and start the encoder */
2456 shadow_io_control_main &= ~(1 << 10);
2457 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2458 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2459
2460 /* Wait until the DSP has accepted the settings */
2461 do
2462 {
2463 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2464 } while(val & 1);
2465 }
2466
2467 is_recording = true;
2468 saving_status = NOT_SAVING;
2469 paused = false;
2470
2471 /* Store the current time */
2472 if(prerecording)
2473 record_start_time = current_tick - prerecord_count * HZ;
2474 else
2475 record_start_time = current_tick;
2476
2477 pause_start_time = 0;
2478
2479 demand_irq_enable(true);
2480}
2481
2482static void pause_recording(void)
2483{
2484 pause_start_time = current_tick;
2485
2486 /* Set the pause bit */
2487 shadow_soft_mute |= 2;
2488 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2489
2490 paused = true;
2491}
2492
2493static void resume_recording(void)
2494{
2495 paused = false;
2496
2497 /* Clear the pause bit */
2498 shadow_soft_mute &= ~2;
2499 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2500
2501 /* Compensate for the time we have been paused */
2502 if(pause_start_time)
2503 {
2504 record_start_time =
2505 current_tick - (pause_start_time - record_start_time);
2506 pause_start_time = 0;
2507 }
2508}
2509
2510static void stop_recording(void)
2511{
2512 unsigned long val;
2513
2514 /* Let it finish the last frame */
2515 if(!paused)
2516 pause_recording();
2517 sleep(HZ/5);
2518
2519 demand_irq_enable(false);
2520
2521 is_recording = false;
2522 is_prerecording = false;
2523
2524 last_rec_bytes = num_rec_bytes;
2525 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2526 last_rec_time = current_tick - record_start_time;
2527
2528 /* Start monitoring */
2529 shadow_io_control_main |= (1 << 10);
2530 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2531 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2532
2533 /* Wait until the DSP has accepted the settings */
2534 do
2535 {
2536 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2537 } while(val & 1);
2538
2539 resume_recording();
2540}
2541
2542void audio_set_recording_options(struct audio_recording_options *options)
2543{
2544 bool is_mpeg1;
2545
2546 is_mpeg1 = (options->rec_frequency < 3);
2547
2548 rec_version_index = is_mpeg1?3:2;
2549 rec_frequency_index = options->rec_frequency % 3;
2550
2551 shadow_encoder_control = (options->rec_quality << 17) |
2552 (rec_frequency_index << 10) |
2553 ((is_mpeg1?1:0) << 9) |
2554 (((options->rec_channels * 2 + 1) & 3) << 6) |
2555 (1 << 5) /* MS-stereo */ |
2556 (1 << 2) /* Is an original */;
2557 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2558
2559 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2560
2561#if CONFIG_TUNER & S1A0903X01
2562 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2563 interference with the Samsung tuner. */
2564 if (rec_frequency_index)
2565 mas_store_pllfreq(24576000);
2566 else
2567 mas_store_pllfreq(22579000);
2568#endif
2569
2570 shadow_soft_mute = options->rec_editable?4:0;
2571 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2572
2573 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2574
2575 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2576 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2577 (1 << 5) | /* SDO strobe invert */
2578 ((is_mpeg1?0:1) << 3) |
2579 (1 << 2) | /* Inverted SIBC clock signal */
2580 1; /* Validate */
2581 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2582
2583 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2584
2585 if(options->rec_source == AUDIO_SRC_MIC)
2586 {
2587 /* Copy left channel to right (mono mode) */
2588 mas_codec_writereg(8, 0x8000);
2589 }
2590 else
2591 {
2592 /* Stereo input mode */
2593 mas_codec_writereg(8, 0);
2594 }
2595
2596 prerecording_max_seconds = options->rec_prerecord_time;
2597 if(prerecording_max_seconds)
2598 {
2599 prerecording = true;
2600 start_prerecording();
2601 }
2602 else
2603 {
2604 prerecording = false;
2605 is_prerecording = false;
2606 is_recording = false;
2607 }
2608}
2609
2610/* If use_mic is true, the left gain is used */
2611void audio_set_recording_gain(int left, int right, int type)
2612{
2613 /* Enable both left and right A/D */
2614 shadow_codec_reg0 = (left << 12) |
2615 (right << 8) |
2616 (left << 4) |
2617 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2618 0x0007;
2619 mas_codec_writereg(0x0, shadow_codec_reg0);
2620}
2621
2622/* try to make some kind of beep, also in recording mode */
2623void audio_beep(int duration)
2624{
2625 long starttick = current_tick;
2626 do
2627 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2628 * While this is still audible even without an external signal,
2629 * it doesn't affect the (pre-)recording. */
2630 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2631 mas_codec_writereg(0, shadow_codec_reg0);
2632 yield();
2633 }
2634 while (current_tick - starttick < duration);
2635}
2636
2637void audio_new_file(const char *filename)
2638{
2639 mpeg_errno = 0;
2640
2641 strlcpy(recording_filename, filename, MAX_PATH);
2642
2643 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2644}
2645
2646unsigned long audio_recorded_time(void)
2647{
2648 if(is_prerecording)
2649 return prerecord_count * HZ;
2650
2651 if(is_recording)
2652 {
2653 if(paused)
2654 return pause_start_time - record_start_time;
2655 else
2656 return current_tick - record_start_time;
2657 }
2658
2659 return 0;
2660}
2661
2662unsigned long audio_num_recorded_bytes(void)
2663{
2664 int num_bytes;
2665 int index;
2666
2667 if(is_recording)
2668 {
2669 if(is_prerecording)
2670 {
2671 index = prerecord_index - prerecord_count;
2672 if(index < 0)
2673 index += prerecording_max_seconds;
2674
2675 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2676 if(num_bytes < 0)
2677 num_bytes += audiobuflen;
2678
2679 return num_bytes;
2680 }
2681 else
2682 return num_rec_bytes;
2683 }
2684 else
2685 return 0;
2686}
2687
2688#else /* SIMULATOR */
2689
2690/* dummies coming up */
2691
2692void audio_init_playback(void)
2693{
2694 /* a dummy */
2695}
2696unsigned long audio_recorded_time(void)
2697{
2698 /* a dummy */
2699 return 0;
2700}
2701void audio_beep(int duration)
2702{
2703 /* a dummy */
2704 (void)duration;
2705}
2706void audio_pause_recording(void)
2707{
2708 /* a dummy */
2709}
2710void audio_resume_recording(void)
2711{
2712 /* a dummy */
2713}
2714unsigned long audio_num_recorded_bytes(void)
2715{
2716 /* a dummy */
2717 return 0;
2718}
2719void audio_record(const char *filename)
2720{
2721 /* a dummy */
2722 (void)filename;
2723}
2724void audio_new_file(const char *filename)
2725{
2726 /* a dummy */
2727 (void)filename;
2728}
2729
2730void audio_set_recording_gain(int left, int right, int type)
2731{
2732 /* a dummy */
2733 (void)left;
2734 (void)right;
2735 (void)type;
2736}
2737void audio_init_recording(void)
2738{
2739 /* a dummy */
2740}
2741void audio_set_recording_options(struct audio_recording_options *options)
2742{
2743 /* a dummy */
2744 (void)options;
2745}
2746#endif /* SIMULATOR */
2747#endif /* CONFIG_CODEC == MAS3587F */
2748
2749size_t audio_buffer_size(void) 1685size_t audio_buffer_size(void)
2750{ 1686{
2751 if (audiobuf_handle > 0) 1687 if (audiobuf_handle > 0)
@@ -2977,14 +1913,6 @@ int audio_status(void)
2977 if(paused) 1913 if(paused)
2978 ret |= AUDIO_STATUS_PAUSE; 1914 ret |= AUDIO_STATUS_PAUSE;
2979 1915
2980#if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2981 if(is_recording && !is_prerecording)
2982 ret |= AUDIO_STATUS_RECORD;
2983
2984 if(is_prerecording)
2985 ret |= AUDIO_STATUS_PRERECORD;
2986#endif /* CONFIG_CODEC == MAS3587F */
2987
2988 if(mpeg_errno) 1916 if(mpeg_errno)
2989 ret |= AUDIO_STATUS_ERROR; 1917 ret |= AUDIO_STATUS_ERROR;
2990 1918
@@ -3039,13 +1967,6 @@ void audio_init(void)
3039 1967
3040 memset(trackdata, 0, sizeof(trackdata)); 1968 memset(trackdata, 0, sizeof(trackdata));
3041 1969
3042#if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3043 if (HW_MASK & PR_ACTIVE_HIGH)
3044 and_b(~0x08, &PADRH);
3045 else
3046 or_b(0x08, &PADRH);
3047#endif /* CONFIG_CODEC == MAS3587F */
3048
3049#ifdef DEBUG 1970#ifdef DEBUG
3050#ifndef SIMULATOR 1971#ifndef SIMULATOR
3051 dbg_timer_start(); 1972 dbg_timer_start();