diff options
Diffstat (limited to 'apps/mpeg.c')
-rw-r--r-- | apps/mpeg.c | 1079 |
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 @@ | |||
81 | extern unsigned long mas_version_code; | 80 | extern unsigned long mas_version_code; |
82 | #endif | 81 | #endif |
83 | 82 | ||
84 | #if CONFIG_CODEC == MAS3587F | ||
85 | extern 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 | ||
188 | static char recording_filename[MAX_PATH]; /* argument to thread */ | ||
189 | static char delayed_filename[MAX_PATH]; /* internal copy of above */ | ||
190 | |||
191 | static char xing_buffer[MAX_XING_HEADER_SIZE]; | ||
192 | |||
193 | static bool init_recording_done; | ||
194 | static bool init_playback_done; | ||
195 | static bool prerecording; /* True if prerecording is enabled */ | ||
196 | static bool is_prerecording; /* True if we are prerecording */ | ||
197 | static bool is_recording; /* We are recording */ | ||
198 | |||
199 | static 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 | |||
206 | static int rec_frequency_index; /* For create_xing_header() calls */ | ||
207 | static int rec_version_index; /* For create_xing_header() calls */ | ||
208 | |||
209 | struct prerecord_info { | ||
210 | int mempos; | ||
211 | unsigned long framecount; | ||
212 | }; | ||
213 | |||
214 | static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS]; | ||
215 | static int prerecord_index; /* Current index in the prerecord buffer */ | ||
216 | static int prerecording_max_seconds; /* Max number of seconds to store */ | ||
217 | static int prerecord_count; /* Number of seconds in the prerecord buffer */ | ||
218 | static int prerecord_timeout; /* The tick count of the next prerecord data | ||
219 | store */ | ||
220 | |||
221 | static unsigned long record_start_time; /* Value of current_tick when recording | ||
222 | was started */ | ||
223 | static unsigned long pause_start_time; /* Value of current_tick when pause was | ||
224 | started */ | ||
225 | static unsigned long last_rec_time; | ||
226 | static unsigned long num_rec_bytes; | ||
227 | static unsigned long last_rec_bytes; | ||
228 | static unsigned long frame_count_start; | ||
229 | static unsigned long frame_count_end; | ||
230 | static unsigned long saved_header = 0; | ||
231 | |||
232 | /* Shadow MAS registers */ | ||
233 | unsigned long shadow_encoder_control = 0; | ||
234 | #endif /* CONFIG_CODEC == MAS3587F */ | ||
235 | |||
236 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
237 | unsigned long shadow_io_control_main = 0; | ||
238 | unsigned long shadow_soft_mute = 0; | ||
239 | unsigned shadow_codec_reg0; | ||
240 | #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ | ||
241 | |||
242 | #ifdef HAVE_RECORDING | 178 | #ifdef HAVE_RECORDING |
243 | static const unsigned char empty_id3_header[] = | 179 | static const unsigned char empty_id3_header[] = |
244 | { | 180 | { |
@@ -253,18 +189,6 @@ static int get_playable_space(void); | |||
253 | static int get_unswapped_space(void); | 189 | static int get_unswapped_space(void); |
254 | #endif /* !SIMULATOR */ | 190 | #endif /* !SIMULATOR */ |
255 | 191 | ||
256 | #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) | ||
257 | static void init_recording(void); | ||
258 | static void prepend_header(void); | ||
259 | static void update_header(void); | ||
260 | static void start_prerecording(void); | ||
261 | static void start_recording(void); | ||
262 | static void stop_recording(void); | ||
263 | static int get_unsaved_space(void); | ||
264 | static void pause_recording(void); | ||
265 | static void resume_recording(void); | ||
266 | #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */ | ||
267 | |||
268 | static void audio_reset_buffer_noalloc(void* buf, size_t bufsize); | 192 | static void audio_reset_buffer_noalloc(void* buf, size_t bufsize); |
269 | static void audio_reset_buffer(void); | 193 | static 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 | ||
762 | static 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 | |||
770 | static 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 | ||
785 | static long timing_info_index = 0; | ||
786 | static long timing_info[1024]; | ||
787 | #endif /* DEBUG */ | ||
788 | |||
789 | void rec_tick (void) __attribute__ ((section (".icode"))); | ||
790 | void 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 | |||
863 | void playback_tick(void) | 676 | void 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 | ||
2200 | void 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 | ***************************************************************************/ | ||
2213 | void 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 | |||
2222 | static 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 | |||
2331 | void 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 | |||
2340 | void audio_pause_recording(void) | ||
2341 | { | ||
2342 | queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0); | ||
2343 | } | ||
2344 | |||
2345 | void audio_resume_recording(void) | ||
2346 | { | ||
2347 | queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0); | ||
2348 | } | ||
2349 | |||
2350 | static 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 | |||
2380 | static 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 | |||
2410 | static 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 | |||
2441 | static 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 | |||
2482 | static 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 | |||
2493 | static 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 | |||
2510 | static 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 | |||
2542 | void 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 */ | ||
2611 | void 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 */ | ||
2623 | void 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 | |||
2637 | void 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 | |||
2646 | unsigned 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 | |||
2662 | unsigned 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 | |||
2692 | void audio_init_playback(void) | ||
2693 | { | ||
2694 | /* a dummy */ | ||
2695 | } | ||
2696 | unsigned long audio_recorded_time(void) | ||
2697 | { | ||
2698 | /* a dummy */ | ||
2699 | return 0; | ||
2700 | } | ||
2701 | void audio_beep(int duration) | ||
2702 | { | ||
2703 | /* a dummy */ | ||
2704 | (void)duration; | ||
2705 | } | ||
2706 | void audio_pause_recording(void) | ||
2707 | { | ||
2708 | /* a dummy */ | ||
2709 | } | ||
2710 | void audio_resume_recording(void) | ||
2711 | { | ||
2712 | /* a dummy */ | ||
2713 | } | ||
2714 | unsigned long audio_num_recorded_bytes(void) | ||
2715 | { | ||
2716 | /* a dummy */ | ||
2717 | return 0; | ||
2718 | } | ||
2719 | void audio_record(const char *filename) | ||
2720 | { | ||
2721 | /* a dummy */ | ||
2722 | (void)filename; | ||
2723 | } | ||
2724 | void audio_new_file(const char *filename) | ||
2725 | { | ||
2726 | /* a dummy */ | ||
2727 | (void)filename; | ||
2728 | } | ||
2729 | |||
2730 | void audio_set_recording_gain(int left, int right, int type) | ||
2731 | { | ||
2732 | /* a dummy */ | ||
2733 | (void)left; | ||
2734 | (void)right; | ||
2735 | (void)type; | ||
2736 | } | ||
2737 | void audio_init_recording(void) | ||
2738 | { | ||
2739 | /* a dummy */ | ||
2740 | } | ||
2741 | void 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 | |||
2749 | size_t audio_buffer_size(void) | 1685 | size_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(); |