/* * Music Player class * * Copyright (C) 2008 Alejandro Valenzuela Roca, * * http://mexinetica.com/~lanjoe9 * * This file is part of MotorJ, a free framework for videogame development. * * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ #include "musicplayer-class.h" #ifdef PC_SDL /* PC SDL implementation */ mjMusicPlayer::mjMusicPlayer() { cMusic = NULL; loop = false; captureFile = NULL; } mjMusicPlayer::~mjMusicPlayer() { StopAudioCapture(); } int mjMusicPlayer::LoadFile(const char * filename) { if (cMusic) // Music had been loaded previously; must free. Mix_FreeMusic(cMusic); cMusic = Mix_LoadMUS(filename); if (cMusic) return true; else return false; } void mjMusicPlayer::Play() { if (cMusic) Mix_PlayMusic(cMusic, -1*loop); } void mjMusicPlayer::Pause() { if (Mix_PausedMusic()) Mix_ResumeMusic(); else Mix_PauseMusic(); } void mjMusicPlayer::setFPS(unsigned short fps) { /* This method does not have any effect in the PC version */ } int mjMusicPlayer::SetAudioCaptureFile(const char* filename) { const char* path = filename; #ifdef SUPPORT_H path = replace_dir_char(filename); #endif captureFile = fopen(path, "w"); return ! captureFile; } void AudioCaptureFunction(void *udata, Uint8 *stream, int len) { // Write the data to the specified file fwrite(stream, len, 1, (FILE* ) udata); } void mjMusicPlayer::StartAudioCapture() { if (captureFile) { Mix_SetPostMix(AudioCaptureFunction, captureFile); } } void mjMusicPlayer::StopAudioCapture() { if (captureFile) { Mix_SetPostMix(NULL, NULL); fclose(captureFile); captureFile = NULL; } } #endif #ifdef NINTENDO_WII /* Nintendo Wii placeholder */ mjMusicPlayer::mjMusicPlayer() { } int mjMusicPlayer::LoadFile(const char * filename) { } void mjMusicPlayer::Play() { } void mjMusicPlayer::Pause() { } void mjMusicPlayer::setFPS(unsigned short fps) { /* This method does not have any effect in the PC version */ } #endif #ifdef NINTENDO_DS /* Nintendo DS implementation */ mjMusicPlayer::mjMusicPlayer() { ov_currentSection = 0; volume = 128; loop = false; loop_start_time = 0; setFPS(30); mplayerfile = NULL; status = MP_IDLE; mustSwitch = false; currentlyReading = false; istopping = false; } int mjMusicPlayer::LoadFile(const char * filename) { // In case something had been open already, we'll close it first if (mplayerfile) { ov_clear(&ov_file); } else status = MP_LOADING; if ((mplayerfile = fopen(filename, "rb")) && (ov_open(mplayerfile, &ov_file, NULL, 0) == 0) ) { ov_info_struct = ov_info(&ov_file, -1); sampleTSD.rate = 44100; sampleTSD.pan = 64; sampleTSD.format = 0; return 1; } return 0; } void mjMusicPlayer::Play() { readBufferCount = 0; status = MP_LOADING; while (readBufferCount < MP_EXPECTED_SIZE) { Update(); } status = MP_PLAYING; } void mjMusicPlayer::Pause() { if (status == MP_PLAYING) status = MP_PAUSED; else status = MP_PLAYING; } void mjMusicPlayer::setFPS(unsigned short fps) { ifps = fps; M_FRAGMENT = 88200/fps; } void mjMusicPlayer::InterruptFunction() { static int seektime = 0; if ((status == MP_PLAYING) && (!mustSwitch)) { //playSound(&sampleTSD); mustSwitch = true; readBufferCount = 0; } else if (status == MP_SEEKING && seektime < 9) { seektime++; if (seektime == 9) status = MP_PLAYING; seektime = 0; } } void mjMusicPlayer::Update() { int currentRead = 1; int thisSampleRead = 0; if ((status == MP_LOADING) || (status == MP_PLAYING)) { while ((currentRead > 0) && (thisSampleRead < M_FRAGMENT) && (readBufferCount < MP_EXPECTED_SIZE)) { currentRead = ov_read(&ov_file, buffers[currentlyReading]+readBufferCount, MP_EXPECTED_SIZE - readBufferCount, &ov_currentsection); thisSampleRead += currentRead; readBufferCount += currentRead; //printf("%d/%d/%d\n", currentRead, thisSampleRead, readBufferCount); } if (!currentRead) { if (loop) { // Do rewind :) ov_time_seek(&ov_file, loop_start_time); } else { // Fill with zeroes int i; for (i = readBufferCount; i < MP_EXPECTED_SIZE; i++) buffers[currentlyReading][i] = 0; readBufferCount = MP_EXPECTED_SIZE; status = MP_STOPPED; ov_clear(&ov_file); //fclose(mplayerfile); // ?needed? } } if (mustSwitch && (readBufferCount == MP_EXPECTED_SIZE)) { sampleTSD.len = readBufferCount; sampleTSD.data = buffers[currentlyReading]; if (status != MP_LOADING) currentlyReading = !currentlyReading; if (volume > 127) volume = 127; sampleTSD.vol = volume; mustSwitch = false; } } } void mjMusicPlayer::TimeSeek(ogg_int64_t ms) { ov_time_seek(&ov_file, ms); } ogg_int64_t mjMusicPlayer::TimePos() { return ov_time_tell(&ov_file); } void mjMusicPlayer::SetCounter(unsigned short * counter) { mplayercount = counter; } void mjMusicPlayer::Sync() { if (mplayercount) * mplayercount = 0; readBufferCount = 0; } void mjMusicPlayer::Unload() { Pause(); ov_clear(&ov_file); fclose(mplayerfile); } #endif