static qboolean S_XMP_CodecOpenStream (snd_stream_t *stream) { /* need to load the whole file into memory and pass it to libxmp * using xmp_load_module_from_memory() which requires libxmp >= 4.2. * libxmp-4.0/4.1 only have xmp_load_module() which accepts a file * name which isn't good with files in containers like paks, etc. */ xmp_context c; byte *moddata; long len; int mark; c = xmp_create_context(); if (c == NULL) return false; len = FS_filelength (&stream->fh); mark = Hunk_LowMark(); moddata = (byte *) Hunk_Alloc(len); FS_fread(moddata, 1, len, &stream->fh); if (xmp_load_module_from_memory(c, moddata, len) != 0) { Con_DPrintf("Could not load module %s\n", stream->name); goto err1; } Hunk_FreeToLowMark(mark); /* free original file data */ stream->priv = c; if (shm->speed > XMP_MAX_SRATE) stream->info.rate = 44100; else if (shm->speed < XMP_MIN_SRATE) stream->info.rate = 11025; else stream->info.rate = shm->speed; stream->info.bits = shm->samplebits; stream->info.width = stream->info.bits / 8; stream->info.channels = shm->channels; if (S_XMP_StartPlay(stream) != 0) goto err2; /* percentual left/right channel separation, default is 70. */ if (stream->info.channels == 2) if (xmp_set_player(c, XMP_PLAYER_MIX, 100) != 0) goto err3; /* interpolation type, default is XMP_INTERP_LINEAR */ if (xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0) goto err3; return true; err3: xmp_end_player(c); err2: xmp_release_module(c); err1: xmp_free_context(c); return false; }
static void _compare_mixer_data(char *mod, char *data, int loops, int ignore_rv) { xmp_context opaque; struct context_data *ctx; struct module_data *m; struct player_data *p; struct mixer_voice *vi; struct xmp_frame_info fi; int time, row, frame, chan, period, note, ins, vol, pan, pos0, cutoff; char line[200]; FILE *f; int i, voc, ret; f = fopen(data, "r"); fail_unless(f != NULL, "can't open data file"); opaque = xmp_create_context(); fail_unless(opaque != NULL, "can't create context"); ret = xmp_load_module(opaque, mod); fail_unless(ret == 0, "can't load module"); ctx = (struct context_data *)opaque; m = &ctx->m; p = &ctx->p; xmp_start_player(opaque, 44100, 0); xmp_set_player(opaque, XMP_PLAYER_MIX, 100); while (1) { xmp_play_frame(opaque); xmp_get_frame_info(opaque, &fi); if (fi.loop_count >= loops) break; for (i = 0; i < m->mod.chn; i++) { struct xmp_channel_info *ci = &fi.channel_info[i]; struct channel_data *xc = &p->xc_data[i]; int num; voc = map_channel(p, i); if (voc < 0 || TEST_NOTE(NOTE_SAMPLE_END)) continue; vi = &p->virt.voice_array[voc]; fgets(line, 200, f); num = sscanf(line, "%d %d %d %d %d %d %d %d %d %d %d", &time, &row, &frame, &chan, &period, ¬e, &ins, &vol, &pan, &pos0, &cutoff); fail_unless(fi.time == time, "time mismatch"); fail_unless(fi.row == row, "row mismatch"); fail_unless(fi.frame == frame, "frame mismatch"); fail_unless(i == chan, "channel mismatch"); fail_unless(ci->period == period, "period mismatch"); fail_unless(vi->note == note, "note mismatch"); fail_unless(vi->ins == ins, "instrument"); if (!ignore_rv) { fail_unless(vi->vol == vol, "volume mismatch"); fail_unless(vi->pan == pan, "pan mismatch"); } fail_unless(vi->pos0 == pos0, "position mismatch"); if (num >= 11) { fail_unless(vi->filter.cutoff == cutoff, "cutoff mismatch"); } } } fgets(line, 200, f); fail_unless(feof(f), "not end of data file"); xmp_end_player(opaque); xmp_release_module(opaque); xmp_free_context(opaque); }
/** * Play music from the specified file. * * @param fileName Name of a file containing music data. */ void playMusic (const char * fileName) { File *file; unsigned char *psmData; int size; bool loadOk = false; #ifdef USE_MODPLUG ModPlug_Settings settings; #endif // Stop any existing music playing stopMusic(); // Load the music file try { file = new File(fileName, false); } catch (int e) { return; } // Find the size of the file size = file->getSize(); // Read the entire file into memory file->seek(0, true); psmData = file->loadBlock(size); delete file; #ifdef USE_MODPLUG // Set up libmodplug settings.mFlags = MUSIC_FLAGS; settings.mChannels = audioSpec.channels; if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_S8)) settings.mBits = 8; else settings.mBits = 16; settings.mFrequency = audioSpec.freq; settings.mResamplingMode = MUSIC_RESAMPLEMODE; settings.mReverbDepth = 25; settings.mReverbDelay = 40; settings.mBassAmount = 50; settings.mBassRange = 10; settings.mSurroundDepth = 50; settings.mSurroundDelay = 40; settings.mLoopCount = -1; ModPlug_SetSettings(&settings); // Load the file into libmodplug musicFile = ModPlug_Load(psmData, size); loadOk = (musicFile != NULL); #elif defined(USE_XMP) // Load the file into libxmp loadOk = (xmp_load_module_from_memory(xmpC, psmData, size) == 0); #endif delete[] psmData; if (!loadOk) { logError("Could not play music file", fileName); return; } #ifdef USE_XMP int playerFlags = 0; if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_S8)) playerFlags = playerFlags & XMP_FORMAT_8BIT; if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_U16) || (audioSpec.format == AUDIO_U16MSB) || (audioSpec.format == AUDIO_U16LSB)) playerFlags = playerFlags & XMP_FORMAT_UNSIGNED; if (audioSpec.channels == 1) playerFlags = playerFlags & XMP_FORMAT_MONO; xmp_start_player(xmpC, audioSpec.freq, playerFlags); xmp_set_player(xmpC, XMP_PLAYER_INTERP, MUSIC_INTERPOLATION); # ifdef MUSIC_EFFECTS xmp_set_player(xmpC, XMP_PLAYER_DSP, MUSIC_EFFECTS); # endif #endif // Start the audio playing SDL_PauseAudio(0); return; }