2 /* Ripped off from Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ */
6 #include <codecs/lib/codeclib.h>
7 #include "libgme/nsf_emu.h"
11 /* Maximum number of bytes to process in one iteration */
12 #define CHUNK_SIZE (1024*2)
14 static int16_t samples
[CHUNK_SIZE
] IBSS_ATTR
;
15 static struct Nsf_Emu nsf_emu
;
17 /****************** rockbox interface ******************/
19 static void set_codec_track(int t
, int multitrack
) {
20 Nsf_start_track(&nsf_emu
, t
);
22 /* for REPEAT_ONE we disable track limits */
23 if (ci
->global_settings
->repeat_mode
!= REPEAT_ONE
) {
24 Track_set_fade(&nsf_emu
, Track_length( &nsf_emu
, t
) - 4000, 4000);
26 if (multitrack
) ci
->set_elapsed(t
*1000); /* t is track no to display */
27 else ci
->set_elapsed(0);
30 /* this is the codec entry point */
31 enum codec_status
codec_main(enum codec_entry_call_reason reason
)
33 if (reason
== CODEC_LOAD
) {
34 /* we only render 16 bits */
35 ci
->configure(DSP_SET_SAMPLE_DEPTH
, 16);
37 /* 44 Khz, Interleaved stereo */
38 ci
->configure(DSP_SET_FREQUENCY
, 44100);
39 ci
->configure(DSP_SET_STEREO_MODE
, STEREO_INTERLEAVED
);
42 Nsf_set_sample_rate(&nsf_emu
, 44100);
48 /* this is called for each file to process */
49 enum codec_status
codec_run(void)
54 int track
, is_multitrack
;
55 uint32_t elapsed_time
;
58 track
= is_multitrack
= 0;
61 DEBUGF("NSF: next_track\n");
66 codec_set_replaygain(ci
->id3
);
68 /* Read the entire file */
69 DEBUGF("NSF: request file\n");
71 buf
= ci
->request_buffer(&n
, ci
->filesize
);
72 if (!buf
|| n
< (size_t)ci
->filesize
) {
73 DEBUGF("NSF: file load failed\n");
77 if ((err
= Nsf_load(&nsf_emu
, buf
, ci
->filesize
))) {
78 DEBUGF("NSF: Nsf_load failed (%s)\n", err
);
82 /* Update internal track count */
83 if (nsf_emu
.m3u
.size
> 0)
84 nsf_emu
.track_count
= nsf_emu
.m3u
.size
;
86 if (nsf_emu
.track_count
> 1) is_multitrack
= 1;
89 set_codec_track(track
, is_multitrack
);
91 /* The main decoder loop */
93 enum codec_command_action action
= ci
->get_command(¶m
);
95 if (action
== CODEC_ACTION_HALT
)
98 if (action
== CODEC_ACTION_SEEK_TIME
) {
102 if (track
>= nsf_emu
.track_count
) break;
106 ci
->set_elapsed(param
);
107 elapsed_time
= param
;
108 Track_seek(&nsf_emu
, param
);
112 if (ci
->global_settings
->repeat_mode
!= REPEAT_ONE
) {
113 Track_set_fade(&nsf_emu
, Track_length( &nsf_emu
, track
), 4000);
117 /* Generate audio buffer */
118 err
= Nsf_play(&nsf_emu
, CHUNK_SIZE
, samples
);
119 if (err
|| nsf_emu
.track_ended
) {
121 if (track
>= nsf_emu
.track_count
) break;
125 ci
->pcmbuf_insert(samples
, NULL
, CHUNK_SIZE
>> 1);
127 /* Set elapsed time for one track files */
128 if (is_multitrack
== 0) {
129 elapsed_time
+= (CHUNK_SIZE
/ 2) / 44.1;
130 ci
->set_elapsed(elapsed_time
);