diff options
Diffstat (limited to 'apps/plugins/codecwav.c')
-rw-r--r-- | apps/plugins/codecwav.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/apps/plugins/codecwav.c b/apps/plugins/codecwav.c index a02f2cdbff..a82c44b25a 100644 --- a/apps/plugins/codecwav.c +++ b/apps/plugins/codecwav.c | |||
@@ -21,15 +21,17 @@ | |||
21 | #include "playback.h" | 21 | #include "playback.h" |
22 | #include "lib/codeclib.h" | 22 | #include "lib/codeclib.h" |
23 | 23 | ||
24 | #define BYTESWAP(x) (((x>>8) & 0xff) | ((x<<8) & 0xff00)) | ||
25 | |||
26 | /* Number of bytes to process in one iteration */ | ||
27 | #define WAV_CHUNK_SIZE 16384 | ||
28 | |||
24 | #ifndef SIMULATOR | 29 | #ifndef SIMULATOR |
25 | extern char iramcopy[]; | 30 | extern char iramcopy[]; |
26 | extern char iramstart[]; | 31 | extern char iramstart[]; |
27 | extern char iramend[]; | 32 | extern char iramend[]; |
28 | #endif | 33 | #endif |
29 | 34 | ||
30 | /* This is probably a waste of IRAM, but why not? */ | ||
31 | static unsigned char wavbuf[16384] IDATA_ATTR; | ||
32 | |||
33 | /* this is the plugin entry point */ | 35 | /* this is the plugin entry point */ |
34 | enum plugin_status plugin_start(struct plugin_api* api, void* parm) | 36 | enum plugin_status plugin_start(struct plugin_api* api, void* parm) |
35 | { | 37 | { |
@@ -37,8 +39,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm) | |||
37 | struct codec_api* ci = (struct codec_api*)parm; | 39 | struct codec_api* ci = (struct codec_api*)parm; |
38 | unsigned long samplerate,numbytes,totalsamples,samplesdone,nsamples; | 40 | unsigned long samplerate,numbytes,totalsamples,samplesdone,nsamples; |
39 | int channels,bytespersample,bitspersample; | 41 | int channels,bytespersample,bitspersample; |
40 | unsigned int i,j,n; | 42 | unsigned int i; |
43 | size_t n; | ||
41 | int endofstream; | 44 | int endofstream; |
45 | unsigned char* header; | ||
46 | unsigned short* wavbuf; | ||
42 | 47 | ||
43 | /* Generic plugin initialisation */ | 48 | /* Generic plugin initialisation */ |
44 | TEST_PLUGIN_API(api); | 49 | TEST_PLUGIN_API(api); |
@@ -62,39 +67,38 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm) | |||
62 | 67 | ||
63 | /* FIX: Correctly parse WAV header - we assume canonical 44-byte header */ | 68 | /* FIX: Correctly parse WAV header - we assume canonical 44-byte header */ |
64 | 69 | ||
65 | n=(unsigned)(ci->read_filebuf(wavbuf,44)); | 70 | header=ci->request_buffer(&n,44); |
66 | if (n!=44) { | 71 | if (n!=44) { |
67 | return PLUGIN_ERROR; | 72 | return PLUGIN_ERROR; |
68 | } | 73 | } |
69 | if ((memcmp(wavbuf,"RIFF",4)!=0) || (memcmp(&wavbuf[8],"WAVEfmt",7)!=0)) { | 74 | if ((memcmp(header,"RIFF",4)!=0) || (memcmp(&header[8],"WAVEfmt",7)!=0)) { |
70 | return PLUGIN_ERROR; | 75 | return PLUGIN_ERROR; |
71 | } | 76 | } |
72 | 77 | ||
73 | samplerate=wavbuf[24]|(wavbuf[25]<<8)|(wavbuf[26]<<16)|(wavbuf[27]<<24); | 78 | samplerate=header[24]|(header[25]<<8)|(header[26]<<16)|(header[27]<<24); |
74 | bitspersample=wavbuf[34]; | 79 | bitspersample=header[34]; |
75 | channels=wavbuf[22]; | 80 | channels=header[22]; |
76 | bytespersample=((bitspersample/8)*channels); | 81 | bytespersample=((bitspersample/8)*channels); |
77 | numbytes=(wavbuf[40]|(wavbuf[41]<<8)|(wavbuf[42]<<16)|(wavbuf[43]<<24)); | 82 | numbytes=(header[40]|(header[41]<<8)|(header[42]<<16)|(header[43]<<24)); |
78 | totalsamples=numbytes/bytespersample; | 83 | totalsamples=numbytes/bytespersample; |
79 | 84 | ||
80 | if ((bitspersample!=16) || (channels != 2)) { | 85 | if ((bitspersample!=16) || (channels != 2)) { |
81 | return PLUGIN_ERROR; | 86 | return PLUGIN_ERROR; |
82 | } | 87 | } |
83 | 88 | ||
89 | ci->advance_buffer(44); | ||
90 | |||
84 | /* The main decoder loop */ | 91 | /* The main decoder loop */ |
85 | 92 | ||
86 | samplesdone=0; | 93 | samplesdone=0; |
87 | ci->set_elapsed(0); | 94 | ci->set_elapsed(0); |
88 | endofstream=0; | 95 | endofstream=0; |
89 | while (!endofstream) { | 96 | while (!endofstream) { |
90 | rb->yield(); | ||
91 | if (ci->stop_codec || ci->reload_codec) { | 97 | if (ci->stop_codec || ci->reload_codec) { |
92 | break; | 98 | break; |
93 | } | 99 | } |
94 | 100 | ||
95 | n=(unsigned)(ci->read_filebuf(wavbuf,sizeof(wavbuf))); | 101 | wavbuf=ci->request_buffer(&n,WAV_CHUNK_SIZE); |
96 | |||
97 | rb->yield(); | ||
98 | 102 | ||
99 | if (n==0) break; /* End of stream */ | 103 | if (n==0) break; /* End of stream */ |
100 | 104 | ||
@@ -110,18 +114,17 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm) | |||
110 | } | 114 | } |
111 | 115 | ||
112 | /* Byte-swap data */ | 116 | /* Byte-swap data */ |
113 | for (i=0;i<n;i+=2) { | 117 | for (i=0;i<n/2;i++) { |
114 | j=wavbuf[i]; | 118 | wavbuf[i]=BYTESWAP(wavbuf[i]); |
115 | wavbuf[i]=wavbuf[i+1]; | ||
116 | wavbuf[i+1]=j; | ||
117 | } | 119 | } |
118 | 120 | ||
119 | samplesdone+=nsamples; | 121 | samplesdone+=nsamples; |
120 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); | 122 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); |
121 | 123 | ||
122 | rb->yield(); | 124 | while (!ci->audiobuffer_insert((unsigned char*)wavbuf, n)) |
123 | while (!ci->audiobuffer_insert(wavbuf, n)) | ||
124 | rb->yield(); | 125 | rb->yield(); |
126 | |||
127 | ci->advance_buffer(n); | ||
125 | } | 128 | } |
126 | 129 | ||
127 | if (ci->request_next_track()) | 130 | if (ci->request_next_track()) |