Mercurial > audlegacy-plugins
comparison src/psf2/plugin.c @ 2742:fd5373830ac1
Initial plugin. Don't use this unless you like aud to use 100% cpu.
| author | William Pitcock <nenolod@atheme.org> |
|---|---|
| date | Mon, 30 Jun 2008 22:12:23 -0500 |
| parents | f16fdcabe069 |
| children | af1338519322 |
comparison
equal
deleted
inserted
replaced
| 2741:f16fdcabe069 | 2742:fd5373830ac1 |
|---|---|
| 26 | 26 |
| 27 #include <stdio.h> | 27 #include <stdio.h> |
| 28 #include <stdlib.h> | 28 #include <stdlib.h> |
| 29 #include <string.h> | 29 #include <string.h> |
| 30 | 30 |
| 31 #include <audacious/plugin.h> | |
| 32 | |
| 31 #include "ao.h" | 33 #include "ao.h" |
| 32 #include "eng_protos.h" | 34 #include "eng_protos.h" |
| 33 | 35 |
| 34 /* file types */ | 36 /* file types */ |
| 35 static uint32 type; | 37 static uint32 type; |
| 37 static struct | 39 static struct |
| 38 { | 40 { |
| 39 uint32 sig; | 41 uint32 sig; |
| 40 char *name; | 42 char *name; |
| 41 int32 (*start)(uint8 *, uint32); | 43 int32 (*start)(uint8 *, uint32); |
| 42 int32 (*gen)(int16 *, uint32); | |
| 43 int32 (*stop)(void); | 44 int32 (*stop)(void); |
| 44 int32 (*command)(int32, int32); | 45 int32 (*command)(int32, int32); |
| 45 uint32 rate; | 46 uint32 rate; |
| 46 int32 (*fillinfo)(ao_display_info *); | 47 int32 (*fillinfo)(ao_display_info *); |
| 47 } types[] = { | 48 } types[] = { |
| 48 { 0x50534602, "Sony PlayStation 2 (.psf2)", psf2_start, psf2_gen, psf2_stop, psf2_command, 60, psf2_fill_info }, | 49 { 0x50534602, "Sony PlayStation 2 (.psf2)", psf2_start, psf2_stop, psf2_command, 60, psf2_fill_info }, |
| 49 { 0xffffffff, "", NULL, NULL, NULL, NULL, 0, NULL } | 50 { 0xffffffff, "", NULL, NULL, NULL, 0, NULL } |
| 50 }; | 51 }; |
| 51 | 52 |
| 52 static char *path; | 53 static char *path; |
| 53 | 54 |
| 54 /* ao_get_lib: called to load secondary files */ | 55 /* ao_get_lib: called to load secondary files */ |
| 55 int ao_get_lib(char *filename, uint8 **buffer, uint64 *length) | 56 int ao_get_lib(char *filename, uint8 **buffer, uint64 *length) |
| 56 { | 57 { |
| 57 uint8 *filebuf; | 58 uint8 *filebuf; |
| 58 uint32 size; | 59 uint32 size; |
| 59 FILE *auxfile; | 60 VFSFile *auxfile; |
| 60 | 61 |
| 61 auxfile = fopen(filename, "rb"); | 62 auxfile = aud_vfs_fopen(filename, "rb"); |
| 62 if (!auxfile) | 63 if (!auxfile) |
| 63 { | 64 { |
| 64 char buf[PATH_MAX]; | 65 char buf[PATH_MAX]; |
| 65 snprintf(buf, PATH_MAX, "%s/%s", dirname(path), filename); | 66 snprintf(buf, PATH_MAX, "%s/%s", dirname(path), filename); |
| 66 auxfile = fopen(buf, "rb"); | 67 auxfile = aud_vfs_fopen(buf, "rb"); |
| 67 | 68 |
| 68 if (!auxfile) | 69 if (!auxfile) |
| 69 { | 70 { |
| 70 printf("Unable to find auxiliary file %s\n", buf); | 71 printf("Unable to find auxiliary file %s\n", buf); |
| 71 return AO_FAIL; | 72 return AO_FAIL; |
| 72 } | 73 } |
| 73 } | 74 } |
| 74 | 75 |
| 75 fseek(auxfile, 0, SEEK_END); | 76 aud_vfs_fseek(auxfile, 0, SEEK_END); |
| 76 size = ftell(auxfile); | 77 size = aud_vfs_ftell(auxfile); |
| 77 fseek(auxfile, 0, SEEK_SET); | 78 aud_vfs_fseek(auxfile, 0, SEEK_SET); |
| 78 | 79 |
| 79 filebuf = malloc(size); | 80 filebuf = malloc(size); |
| 80 | 81 |
| 81 if (!filebuf) | 82 if (!filebuf) |
| 82 { | 83 { |
| 83 fclose(auxfile); | 84 aud_vfs_fclose(auxfile); |
| 84 printf("ERROR: could not allocate %d bytes of memory\n", size); | 85 printf("ERROR: could not allocate %d bytes of memory\n", size); |
| 85 return AO_FAIL; | 86 return AO_FAIL; |
| 86 } | 87 } |
| 87 | 88 |
| 88 fread(filebuf, size, 1, auxfile); | 89 aud_vfs_fread(filebuf, size, 1, auxfile); |
| 89 fclose(auxfile); | 90 aud_vfs_fclose(auxfile); |
| 90 | 91 |
| 91 *buffer = filebuf; | 92 *buffer = filebuf; |
| 92 *length = (uint64)size; | 93 *length = (uint64)size; |
| 93 | 94 |
| 94 return AO_SUCCESS; | 95 return AO_SUCCESS; |
| 95 } | 96 } |
| 96 | 97 |
| 97 int main(int argv, char *argc[]) | 98 void psf2_play(InputPlayback *data) |
| 98 { | 99 { |
| 99 FILE *file; | 100 VFSFile *file; |
| 100 uint8 *buffer; | 101 uint8 *buffer; |
| 101 uint32 size, filesig; | 102 uint32 size, filesig; |
| 102 | 103 |
| 103 path = strdup(argc[1]); | 104 path = strdup(data->filename); |
| 104 file = fopen(argc[1], "rb"); | 105 file = aud_vfs_fopen(data->filename, "rb"); |
| 105 | 106 |
| 106 if (!file) | 107 if (!file) |
| 107 { | 108 { |
| 108 printf("ERROR: could not open file %s\n", argc[1]); | 109 printf("ERROR: could not open file %s\n", data->filename); |
| 109 return -1; | 110 return; |
| 110 } | 111 } |
| 111 | 112 |
| 112 // get the length of the file by seeking to the end then reading the current position | 113 aud_vfs_fseek(file, 0, SEEK_END); |
| 113 fseek(file, 0, SEEK_END); | 114 size = aud_vfs_ftell(file); |
| 114 size = ftell(file); | 115 aud_vfs_fseek(file, 0, SEEK_SET); |
| 115 // reset the pointer | |
| 116 fseek(file, 0, SEEK_SET); | |
| 117 | 116 |
| 118 buffer = malloc(size); | 117 buffer = malloc(size); |
| 119 | 118 |
| 120 if (!buffer) | 119 if (!buffer) |
| 121 { | 120 { |
| 122 fclose(file); | 121 aud_vfs_fclose(file); |
| 123 printf("ERROR: could not allocate %d bytes of memory\n", size); | 122 printf("ERROR: could not allocate %d bytes of memory\n", size); |
| 124 return -1; | 123 return; |
| 125 } | 124 } |
| 126 | 125 |
| 127 // read the file | 126 // read the file |
| 128 fread(buffer, size, 1, file); | 127 aud_vfs_fread(buffer, size, 1, file); |
| 129 fclose(file); | 128 aud_vfs_fclose(file); |
| 130 | 129 |
| 131 // now try to identify the file | 130 // now try to identify the file |
| 132 type = 0; | 131 type = 0; |
| 133 filesig = buffer[0]<<24 | buffer[1]<<16 | buffer[2]<<8 | buffer[3]; | 132 filesig = buffer[0]<<24 | buffer[1]<<16 | buffer[2]<<8 | buffer[3]; |
| 134 while (types[type].sig != 0xffffffff) | 133 while (types[type].sig != 0xffffffff) |
| 146 // now did we identify it above or just fall through? | 145 // now did we identify it above or just fall through? |
| 147 if (types[type].sig == 0xffffffff) | 146 if (types[type].sig == 0xffffffff) |
| 148 { | 147 { |
| 149 printf("ERROR: File is unknown, signature bytes are %02x %02x %02x %02x\n", buffer[0], buffer[1], buffer[2], buffer[3]); | 148 printf("ERROR: File is unknown, signature bytes are %02x %02x %02x %02x\n", buffer[0], buffer[1], buffer[2], buffer[3]); |
| 150 free(buffer); | 149 free(buffer); |
| 151 return -1; | 150 return; |
| 152 } | 151 } |
| 153 | 152 |
| 154 if (psf2_start(buffer, size) != AO_SUCCESS) | 153 if (psf2_start(buffer, size) != AO_SUCCESS) |
| 155 { | 154 { |
| 156 free(buffer); | 155 free(buffer); |
| 157 printf("ERROR: Engine rejected file!\n"); | 156 printf("ERROR: Engine rejected file!\n"); |
| 158 return -1; | 157 return; |
| 159 } | 158 } |
| 160 | 159 |
| 161 m1sdr_Init(44100); | 160 data->output->open_audio(FMT_S16_NE, 44100, 2); |
| 162 m1sdr_SetCallback(psf2_gen); | 161 |
| 163 | 162 data->playing = TRUE; |
| 164 while (1) | 163 data->set_pb_ready(data); |
| 165 { | 164 while (data->playing) |
| 166 m1sdr_TimeCheck(); | 165 { |
| 167 } | 166 psf2_execute(data); |
| 167 } | |
| 168 | 168 |
| 169 free(buffer); | 169 free(buffer); |
| 170 | 170 } |
| 171 return 1; | 171 |
| 172 } | 172 void psf2_update(unsigned char *buffer, long count, InputPlayback *playback) |
| 173 | 173 { |
| 174 const int mask = ~((((16 / 8) * 2)) - 1); | |
| 175 | |
| 176 while (count > 0) | |
| 177 { | |
| 178 int t = playback->output->buffer_free() & mask; | |
| 179 if (t > count) | |
| 180 playback->pass_audio(playback, FMT_S16_NE, 2, count, buffer, NULL); | |
| 181 else | |
| 182 { | |
| 183 if (t) | |
| 184 playback->pass_audio(playback, FMT_S16_NE, 2, t, buffer, NULL); | |
| 185 | |
| 186 g_usleep((count-t)*1000*5/441/2); | |
| 187 } | |
| 188 count -= t; | |
| 189 buffer += t; | |
| 190 } | |
| 191 | |
| 192 #if 0 | |
| 193 if (seek) | |
| 194 { | |
| 195 if(sexypsf_seek(seek)) | |
| 196 { | |
| 197 playback->output->flush(seek); | |
| 198 seek = 0; | |
| 199 } | |
| 200 else // negative time - must make a C time machine | |
| 201 { | |
| 202 sexypsf_stop(); | |
| 203 return; | |
| 204 } | |
| 205 } | |
| 206 if (stop) | |
| 207 sexypsf_stop(); | |
| 208 #endif | |
| 209 } | |
| 210 | |
| 211 void psf2_Stop(InputPlayback *playback) | |
| 212 { | |
| 213 playback->playing = FALSE; | |
| 214 } | |
| 215 | |
| 216 void psf2_pause(InputPlayback *playback, short p) | |
| 217 { | |
| 218 playback->output->pause(p); | |
| 219 } | |
| 220 | |
| 221 static int | |
| 222 is_our_fd(gchar *filename, VFSFile *file) | |
| 223 { | |
| 224 gchar magic[4]; | |
| 225 aud_vfs_fread(magic, 1, 4, file); | |
| 226 | |
| 227 if (!memcmp(magic, "PSF\x02", 4)) | |
| 228 return 1; | |
| 229 | |
| 230 return 0; | |
| 231 } | |
| 232 | |
| 233 gchar *psf2_fmts[] = { "psf2", "minipsf2", NULL }; | |
| 234 | |
| 235 InputPlugin psf2_ip = | |
| 236 { | |
| 237 .description = "PSF2 Audio Plugin", | |
| 238 .play_file = psf2_play, | |
| 239 .stop = psf2_Stop, | |
| 240 .pause = psf2_pause, | |
| 241 #if 0 | |
| 242 .seek = sexypsf_xmms_seek, | |
| 243 .get_song_info = sexypsf_xmms_getsonginfo, | |
| 244 .get_song_tuple = get_aud_tuple_psf, | |
| 245 #endif | |
| 246 .is_our_file_from_vfs = is_our_fd, | |
| 247 .vfs_extensions = psf2_fmts, | |
| 248 }; | |
| 249 | |
| 250 InputPlugin *psf2_iplist[] = { &psf2_ip, NULL }; | |
| 251 | |
| 252 DECLARE_PLUGIN(psf2, NULL, NULL, psf2_iplist, NULL, NULL, NULL, NULL, NULL); | |
| 253 |
