long duh_render( DUH_SIGRENDERER *sigrenderer, int bits, int unsign, float volume, float delta, long size, void *sptr ) { long n; sample_t **sampptr; int n_channels; ASSERT(bits == 8 || bits == 16); ASSERT(sptr); if (!sigrenderer) return 0; n_channels = duh_sigrenderer_get_n_channels(sigrenderer); ASSERT(n_channels > 0); /* This restriction will be removed when need be. At the moment, tightly * optimised loops exist for exactly one or two channels. */ ASSERT(n_channels <= 2); sampptr = allocate_sample_buffer(n_channels, size); if (!sampptr) return 0; dumb_silence(sampptr[0], n_channels * size); size = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, sampptr); if (bits == 16) { int signconv = unsign ? 0x8000 : 0x0000; for (n = 0; n < size * n_channels; n++) { CONVERT16(sampptr[0][n], n, signconv); } } else { char signconv = unsign ? 0x80 : 0x00; for (n = 0; n < size * n_channels; n++) { CONVERT8(sampptr[0][n], n, signconv); } } destroy_sample_buffer(sampptr); return size; }
long duh_render_float(DUH_SIGRENDERER *sigrenderer, sample_t ***sig_samples, long *sig_samples_size, int bits, float volume, float delta, long size, void *sptr) { long n; sample_t **sampptr; int n_channels; ASSERT(bits == 32 || bits == 64); ASSERT(sptr); ASSERT(sig_samples); ASSERT(sig_samples_size); if (!sigrenderer) return 0; n_channels = duh_sigrenderer_get_n_channels(sigrenderer); ASSERT(n_channels > 0); /* This restriction will be removed when need be. At the moment, tightly * optimised loops exist for exactly one or two channels. */ ASSERT(n_channels <= 2); if ((*sig_samples == NULL) || (*sig_samples_size != size)) { destroy_sample_buffer(*sig_samples); *sig_samples = allocate_sample_buffer(n_channels, size); *sig_samples_size = size; } sampptr = *sig_samples; if (!sampptr) return 0; dumb_silence(sampptr[0], n_channels * size); size = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, sampptr); if (bits == 64) { for (n = 0; n < size * n_channels; n++) { CONVERT64F(sampptr[0][n], n); } } else if (bits == 32) { for (n = 0; n < size * n_channels; n++) { CONVERT32F(sampptr[0][n], n); } } return size; }
DUMBA5_PLAYER * dumba5_encapsulate_sigrenderer(DUH_SIGRENDERER * sigrenderer, float volume, long bufsize, int freq) { DUMBA5_PLAYER * dp; int n_channels; ALLEGRO_CHANNEL_CONF c_conf; if (!sigrenderer) return NULL; dp = (DUMBA5_PLAYER *) malloc(sizeof(*dp)); if (!dp) return NULL; n_channels = duh_sigrenderer_get_n_channels(sigrenderer); if(n_channels == 1) { c_conf = ALLEGRO_CHANNEL_CONF_1; } else { c_conf = ALLEGRO_CHANNEL_CONF_2; } /* This restriction is imposed by Allegro. */ ASSERT(n_channels > 0); ASSERT(n_channels <= 2); dp->flags = ADP_PLAYING; dp->bufsize = bufsize; dp->freq = freq; dp->stream = al_create_audio_stream(4, bufsize, freq, ALLEGRO_AUDIO_DEPTH_UINT16, c_conf); if (!dp->stream) { free(dp); return NULL; } dp->stream = al_create_audio_stream(4, bufsize, freq, ALLEGRO_AUDIO_DEPTH_UINT16, c_conf); if (!dp->stream) { free(dp); return NULL; } dp->volume = volume; dp->silentcount = 0; return dp; }
int al_poll_duh(AL_DUH_PLAYER *dp) { unsigned short *sptr; long n; long size; int n_channels; if (!dp || !dp->sigrenderer) return 1; if (!(dp->flags & ADP_PLAYING)) return 0; sptr = get_audio_stream_buffer(dp->stream); if (!sptr) return 0; n = duh_render(dp->sigrenderer, 16, 1, dp->volume, 65536.0 / dp->freq, dp->bufsize, sptr); if (n == 0) { if (++dp->silentcount >= 2) { duh_end_sigrenderer(dp->sigrenderer); free_audio_stream_buffer(dp->stream); stop_audio_stream(dp->stream); dp->sigrenderer = NULL; return 1; } } n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer); n *= n_channels; size = dp->bufsize * n_channels; for (; n < size; n++) sptr[n] = 0x8000; free_audio_stream_buffer(dp->stream); return 0; }
AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq) { AL_DUH_PLAYER *dp; int n_channels; if (!sigrenderer) return NULL; dp = malloc(sizeof(*dp)); if (!dp) return NULL; n_channels = duh_sigrenderer_get_n_channels(sigrenderer); /* This restriction is imposed by Allegro. */ ASSERT(n_channels > 0); ASSERT(n_channels <= 2); dp->flags = ADP_PLAYING; dp->bufsize = bufsize; dp->freq = freq; dp->stream = play_audio_stream(bufsize, 16, n_channels - 1, freq, 255, 128); if (!dp->stream) { free(dp); return NULL; } voice_set_priority(dp->stream->voice, 255); dp->sigrenderer = sigrenderer; dp->volume = volume; dp->silentcount = 0; return dp; }
void* Init(const char* strFile, unsigned int filecache, int* channels, int* samplerate, int* bitspersample, int64_t* totaltime, int* bitrate, AEDataFormat* format, const AEChannel** channelinfo) { void* file = XBMC->OpenFile(strFile,0); if (!file) return NULL; dumbfile_mem_status memdata; memdata.size = XBMC->GetFileLength(file); memdata.ptr = new uint8_t[memdata.size]; XBMC->ReadFile(file, const_cast<uint8_t*>(memdata.ptr), memdata.size); XBMC->CloseFile(file); DUMBFILE* f = dumbfile_open_ex(&memdata, &mem_dfs); if (!f) return NULL; DumbContext* result = new DumbContext; if (memdata.size >= 4 && memdata.ptr[0] == 'I' && memdata.ptr[1] == 'M' && memdata.ptr[2] == 'P' && memdata.ptr[3] == 'M') { result->module = dumb_read_it(f); } else if (memdata.size >= 17 && memcmp(memdata.ptr, "Extended Module: ", 17) == 0) { result->module = dumb_read_xm(f); } else if (memdata.size >= 0x30 && memdata.ptr[0x2C] == 'S' && memdata.ptr[0x2D] == 'C' && memdata.ptr[0x2E] == 'R' && memdata.ptr[0x2F] == 'M') { result->module = dumb_read_s3m(f); } else { dumbfile_close(f); delete result; return NULL; } dumbfile_close(f); result->sr = duh_start_sigrenderer(result->module, 0, 2, 0); if (!result->sr) { delete result; return NULL; } *channels = 2; *samplerate = 48000; *bitspersample = 16; *totaltime = duh_get_length(result->module)/65536*1000; *format = AE_FMT_S16NE; static enum AEChannel map[3] = { AE_CH_FL, AE_CH_FR , AE_CH_NULL}; *channelinfo = map; *bitrate = duh_sigrenderer_get_n_channels(result->sr); return result; }
/* DEPRECATED */ int duh_renderer_get_n_channels(DUH_SIGRENDERER *dr) { return duh_sigrenderer_get_n_channels(dr); }
void * dumba5_update_thread(ALLEGRO_THREAD * thread, void * arg) { DUMBA5_PLAYER * dp = (DUMBA5_PLAYER *)arg; ALLEGRO_EVENT_QUEUE * queue; unsigned short *fragment; long n; long size; int n_channels; queue = al_create_event_queue(); al_register_event_source(queue, al_get_audio_stream_event_source(dp->stream)); while(1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if(event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { fragment = (unsigned short *)al_get_audio_stream_fragment(dp->stream); if(!fragment) { return NULL; } n = duh_render(dp->sigrenderer, 16, 0, dp->volume, 65536.0 / dp->freq, dp->bufsize, fragment); if (n == 0) { if (++dp->silentcount >= 2) { duh_end_sigrenderer(dp->sigrenderer); if(!al_set_audio_stream_fragment(dp->stream, fragment)) { } al_destroy_audio_stream(dp->stream); dp->sigrenderer = NULL; return NULL; } } n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer); n *= n_channels; size = dp->bufsize * n_channels; for (; n < size; n++) { fragment[n] = 0x8000; } if(!al_set_audio_stream_fragment(dp->stream, fragment)) { } } if(al_get_thread_should_stop(thread)) { break; } } al_destroy_event_queue(queue); return NULL; }