00001 #include <stdlib.h>
00002 #include "input_mod.h"
00003 #include "debug.h"
00004
00005
00006 namespace audiere {
00007
00008 MODInputStream::MODInputStream() {
00009 m_duh = 0;
00010 m_renderer = 0;
00011 }
00012
00013
00014 MODInputStream::~MODInputStream() {
00015 if (m_renderer) {
00016 duh_end_sigrenderer(m_renderer);
00017 m_renderer = 0;
00018 }
00019
00020 if (m_duh) {
00021 unload_duh(m_duh);
00022 m_duh = 0;
00023 }
00024 }
00025
00026
00027 bool
00028 MODInputStream::initialize(FilePtr file) {
00029
00030 static bool initialized = false;
00031 if (!initialized) {
00032 ADR_GUARD("Initializing DUMB");
00033
00034 atexit(dumb_exit);
00035
00036 static DUMBFILE_SYSTEM dfs = {
00037 dfs_open,
00038 dfs_skip,
00039 dfs_getc,
00040 dfs_getnc,
00041 dfs_close,
00042 };
00043 register_dumbfile_system(&dfs);
00044
00045
00046 dumb_resampling_quality = DUMB_RQ_LINEAR;
00047
00048 initialized = true;
00049 }
00050
00051 m_file = file;
00052
00053 m_duh = openDUH();
00054 if (!m_duh) {
00055 return false;
00056 }
00057
00058 m_renderer = duh_start_sigrenderer(m_duh, 0, 2, 0);
00059 if (!m_renderer) {
00060 unload_duh(m_duh);
00061 m_duh = 0;
00062 return false;
00063 }
00064
00065 DUMB_IT_SIGRENDERER* renderer = duh_get_it_sigrenderer(m_renderer);
00066 dumb_it_set_loop_callback(renderer, &MODInputStream::loopCallback, this);
00067
00068 return true;
00069 }
00070
00071
00072 void
00073 MODInputStream::getFormat(
00074 int& channel_count,
00075 int& sample_rate,
00076 SampleFormat& sample_format)
00077 {
00078 channel_count = 2;
00079 sample_rate = 44100;
00080 sample_format = SF_S16;
00081 }
00082
00083
00084 void
00085 MODInputStream::reset() {
00086 ADR_GUARD("MOD_Reset");
00087 DUH_SIGRENDERER* renderer = duh_start_sigrenderer(m_duh, 0, 2, 0);
00088 if (renderer) {
00089 if (m_renderer) {
00090 duh_end_sigrenderer(m_renderer);
00091 }
00092 m_renderer = renderer;
00093
00094 DUMB_IT_SIGRENDERER* renderer = duh_get_it_sigrenderer(m_renderer);
00095 dumb_it_set_loop_callback(renderer, &MODInputStream::loopCallback, this);
00096 }
00097 }
00098
00099
00100 int
00101 MODInputStream::doRead(int frame_count, void* buffer) {
00102 return duh_render(m_renderer, 16, 0, 1.0f, 65536.0f / 44100,
00103 frame_count, buffer);
00104 }
00105
00106
00107 DUH*
00108 MODInputStream::openDUH() {
00109 const char* filename = (const char*)m_file.get();
00110
00111 DUH* duh = dumb_load_it(filename);
00112 if (duh) return duh;
00113 m_file->seek(0, File::BEGIN);
00114
00115 duh = dumb_load_xm(filename);
00116 if (duh) return duh;
00117 m_file->seek(0, File::BEGIN);
00118
00119 duh = dumb_load_s3m(filename);
00120 if (duh) return duh;
00121 m_file->seek(0, File::BEGIN);
00122
00123 return dumb_load_mod(filename);
00124 }
00125
00126
00127 void*
00128 MODInputStream::dfs_open(const char* filename) {
00129 return const_cast<char*>(filename);
00130 }
00131
00132
00133 int
00134 MODInputStream::dfs_skip(void* f, long n) {
00135 File* file = (File*)f;
00136 if (file->seek(n, File::CURRENT)) {
00137 return 0;
00138 } else {
00139 return -1;
00140 }
00141 }
00142
00143
00144 int
00145 MODInputStream::dfs_getc(void* f) {
00146 File* file = (File*)f;
00147 unsigned char c;
00148 if (file->read(&c, 1) == 1) {
00149 return c;
00150 } else {
00151 return -1;
00152 }
00153 }
00154
00155
00156 long
00157 MODInputStream::dfs_getnc(char* ptr, long n, void* f) {
00158 File* file = (File*)f;
00159 return file->read(ptr, n);
00160 }
00161
00162
00163 void
00164 MODInputStream::dfs_close(void* f) {
00165
00166 }
00167
00168 int
00169 MODInputStream::loopCallback(void* ptr) {
00170 MODInputStream* This = (MODInputStream*)ptr;
00171 return (This->getRepeat() ? 0 : -1);
00172 }
00173
00174 }