+static void mix_samples(short *dest_buf, int *ym_buf, short *mp3_buf, int len, int stereo)
+{
+ if (mp3_buf)
+ {
+ if (stereo)
+ {
+ for (; len > 0; len--)
+ {
+ int l, r;
+ l = r = *dest_buf;
+ l += *ym_buf++; r += *ym_buf++;
+ l += *mp3_buf++; r += *mp3_buf++;
+ Limit( l, MAXOUT, MINOUT );
+ Limit( r, MAXOUT, MINOUT );
+ *dest_buf++ = l; *dest_buf++ = r;
+ }
+ } else {
+ for (; len > 0; len--)
+ {
+ int l = *ym_buf++;
+ l += *dest_buf;
+ l += *mp3_buf++;
+ Limit( l, MAXOUT, MINOUT );
+ *dest_buf++ = l;
+ }
+ }
+ }
+ else
+ {
+ if (stereo)
+ {
+ for (; len > 0; len--)
+ {
+ int l, r;
+ l = r = *dest_buf;
+ l += *ym_buf++, r += *ym_buf++;
+ Limit( l, MAXOUT, MINOUT );
+ Limit( r, MAXOUT, MINOUT );
+ *dest_buf++ = l; *dest_buf++ = r;
+ }
+ } else {
+ for (; len > 0; len--)
+ {
+ int l = *ym_buf++;
+ l += *dest_buf;
+ Limit( l, MAXOUT, MINOUT );
+ *dest_buf++ = l;
+ }
+ }
+ }
+}
+
+#if 0
+static void local_decode(void)
+{
+ int mp3_offs = shared_ctl->mp3_offs;
+ unsigned char *readPtr = mp3_mem + mp3_offs;
+ int bytesLeft = shared_ctl->mp3_len - mp3_offs;
+ int offset; // frame offset from readPtr
+ int err = 0;
+
+ if (bytesLeft <= 0) return; // EOF, nothing to do
+
+ offset = MP3FindSyncWord(readPtr, bytesLeft);
+ if (offset < 0) {
+ shared_ctl->mp3_offs = shared_ctl->mp3_len;
+ return; // EOF
+ }
+ readPtr += offset;
+ bytesLeft -= offset;
+
+ err = MP3Decode(shared_data->mp3dec, &readPtr, &bytesLeft,
+ shared_data->mp3_buffer[shared_ctl->mp3_buffsel], 0);
+ if (err) {
+ if (err == ERR_MP3_INDATA_UNDERFLOW) {
+ shared_ctl->mp3_offs = shared_ctl->mp3_len; // EOF
+ return;
+ } else if (err <= -6 && err >= -12) {
+ // ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_*
+ // just try to skip the offending frame..
+ readPtr++;
+ }
+ shared_ctl->mp3_errors++;
+ shared_ctl->mp3_lasterr = err;
+ }
+ shared_ctl->mp3_offs = readPtr - mp3_mem;
+}
+#endif
+
+
+
+
+static FILE *loaded_mp3 = 0;
+