diff options
Diffstat (limited to 'src/midiplay')
-rw-r--r-- | src/midiplay/Makefile | 12 | ||||
-rw-r--r-- | src/midiplay/Makefile.win32 | 12 | ||||
-rw-r--r-- | src/midiplay/adlmidiplay.cpp | 338 | ||||
-rwxr-xr-x | src/midiplay/wave_writer.c | 170 | ||||
-rwxr-xr-x | src/midiplay/wave_writer.h | 21 |
5 files changed, 0 insertions, 553 deletions
diff --git a/src/midiplay/Makefile b/src/midiplay/Makefile deleted file mode 100644 index f2512b4..0000000 --- a/src/midiplay/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -all: midiplay - -midiplay: adlmidiplay.o wave_writer.o - g++ $^ -Wl,-rpath='$$ORIGIN' -L../../bin -ladlmidi -lSDL2 -o ../../bin/adlmidiplay - rm *.o - -adlmidiplay.o: adlmidiplay.cpp - g++ -c $^ -I.. -o adlmidiplay.o - -wave_writer.o: wave_writer.c - gcc -c $^ -I.. -o wave_writer.o - diff --git a/src/midiplay/Makefile.win32 b/src/midiplay/Makefile.win32 deleted file mode 100644 index 05e192f..0000000 --- a/src/midiplay/Makefile.win32 +++ /dev/null @@ -1,12 +0,0 @@ -all: midiplay - -midiplay: adlmidiplay.o wave_writer.o - g++ $^ -L../../bin -ladlmidi -lSDL2 -o ../../bin/adlmidiplay - rm *.o - -adlmidiplay.o: adlmidiplay.cpp - g++ -c $^ -I.. -o adlmidiplay.o - -wave_writer.o: wave_writer.c - gcc -c $^ -I.. -o wave_writer.o - diff --git a/src/midiplay/adlmidiplay.cpp b/src/midiplay/adlmidiplay.cpp deleted file mode 100644 index 7c8766d..0000000 --- a/src/midiplay/adlmidiplay.cpp +++ /dev/null @@ -1,338 +0,0 @@ - -#include <vector> -#include <string> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <deque> -#include <signal.h> -#define SDL_MAIN_HANDLED -#include <SDL2/SDL.h> - -#include <adlmidi.h> - -#include "wave_writer.h" - -class MutexType -{ - SDL_mutex *mut; -public: - MutexType() : mut(SDL_CreateMutex()) { } - ~MutexType() - { - SDL_DestroyMutex(mut); - } - void Lock() - { - SDL_mutexP(mut); - } - void Unlock() - { - SDL_mutexV(mut); - } -}; - - -static std::deque<short> AudioBuffer; -static MutexType AudioBuffer_lock; - -static void SDL_AudioCallbackX(void *, Uint8 *stream, int len) -{ - SDL_LockAudio(); - short *target = (short *) stream; - AudioBuffer_lock.Lock(); - /*if(len != AudioBuffer.size()) - fprintf(stderr, "len=%d stereo samples, AudioBuffer has %u stereo samples", - len/4, (unsigned) AudioBuffer.size()/2);*/ - unsigned ate = (unsigned)len / 2; // number of shorts - if(ate > AudioBuffer.size()) - ate = (unsigned)AudioBuffer.size(); - for(unsigned a = 0; a < ate; ++a) - { - target[a] = AudioBuffer[a]; - } - AudioBuffer.erase(AudioBuffer.begin(), AudioBuffer.begin() + ate); - AudioBuffer_lock.Unlock(); - SDL_UnlockAudio(); -} - -static bool is_number(const std::string &s) -{ - std::string::const_iterator it = s.begin(); - while(it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -static void printError(const char *err) -{ - std::fprintf(stderr, "\nERROR: %s\n\n", err); - std::fflush(stderr); -} - -static int stop = 0; -static void sighandler(int dum) -{ - if((dum == SIGINT) - || (dum == SIGTERM) - #ifndef _WIN32 - || (dum == SIGHUP) - #endif - ) - stop = 1; -} - -int main(int argc, char **argv) -{ - if(argc < 2 || std::string(argv[1]) == "--help" || std::string(argv[1]) == "-h") - { - std::printf( - "Usage: adlmidi <midifilename> [ <options> ] [ <bank> [ <numcards> [ <numfourops>] ] ]\n" - " -p Enables adlib percussion instrument mode\n" - " -t Enables tremolo amplification mode\n" - " -v Enables vibrato amplification mode\n" - " -s Enables scaling of modulator volumes\n" - " -nl Quit without looping\n" - " -w Write WAV file rather than playing\n" - "\n" - "Where <bank> - number of embeeded bank or filepath to custom WOPL bank file\n" - "\n" - "Note: To create WOPL bank files use OPL Bank Editor you can get here: \n" - "https://github.com/Wohlstand/OPL3BankEditor\n" - "\n" - ); - - int banksCount = adl_getBanksCount(); - const char *const *banknames = adl_getBankNames(); - - if(banksCount > 0) - { - std::printf(" Available embedded banks by number:\n\n"); - - for(int a = 0; a < banksCount; ++a) - std::printf("%10s%2u = %s\n", a ? "" : "Banks:", a, banknames[a]); - - std::printf( - "\n" - " Use banks 2-5 to play Descent \"q\" soundtracks.\n" - " Look up the relevant bank number from descent.sng.\n" - "\n" - " The fourth parameter can be used to specify the number\n" - " of four-op channels to use. Each four-op channel eats\n" - " the room of two regular channels. Use as many as required.\n" - " The Doom & Hexen sets require one or two, while\n" - " Miles four-op set requires the maximum of numcards*6.\n" - "\n" - ); - } - else - { - std::printf(" This build of libADLMIDI has no embedded banks!\n\n"); - } - - return 0; - } - - //const unsigned MaxSamplesAtTime = 512; // 512=dbopl limitation - // How long is SDL buffer, in seconds? - // The smaller the value, the more often SDL_AudioCallBack() - // is called. - const double AudioBufferLength = 0.08; - // How much do WE buffer, in seconds? The smaller the value, - // the more prone to sound chopping we are. - const double OurHeadRoomLength = 0.1; - // The lag between visual content and audio content equals - // the sum of these two buffers. - SDL_AudioSpec spec; - SDL_AudioSpec obtained; - - spec.freq = 44100; - spec.format = AUDIO_S16SYS; - spec.channels = 2; - spec.samples = Uint16((double)spec.freq * AudioBufferLength); - spec.callback = SDL_AudioCallbackX; - - ADL_MIDIPlayer *myDevice; - myDevice = adl_init(44100); - if(myDevice == NULL) - { - printError("Failed to init MIDI device!\n"); - return 1; - } - - bool recordWave = false; - - adl_setLoopEnabled(myDevice, 1); - - while(argc > 2) - { - bool had_option = false; - - if(!std::strcmp("-p", argv[2])) - adl_setPercMode(myDevice, 1); - else if(!std::strcmp("-v", argv[2])) - adl_setHVibrato(myDevice, 1); - else if(!std::strcmp("-w", argv[2])) - { - recordWave = true; - adl_setLoopEnabled(myDevice, 0);//Disable loop while record WAV - } - else if(!std::strcmp("-t", argv[2])) - adl_setHTremolo(myDevice, 1); - else if(!std::strcmp("-nl", argv[2])) - adl_setLoopEnabled(myDevice, 0); - else if(!std::strcmp("-s", argv[2])) - adl_setScaleModulators(myDevice, 1); - else break; - - std::copy(argv + (had_option ? 4 : 3), argv + argc, - argv + 2); - argc -= (had_option ? 2 : 1); - } - - if(!recordWave) - { - // Set up SDL - if(SDL_OpenAudio(&spec, &obtained) < 0) - { - std::fprintf(stderr, "\nERROR: Couldn't open audio: %s\n\n", SDL_GetError()); - std::fflush(stderr); - //return 1; - } - if(spec.samples != obtained.samples) - { - std::fprintf(stderr, "Wanted (samples=%u,rate=%u,channels=%u); obtained (samples=%u,rate=%u,channels=%u)\n", - spec.samples, spec.freq, spec.channels, - obtained.samples, obtained.freq, obtained.channels); - std::fflush(stderr); - } - } - - if(argc >= 3) - { - if(is_number(argv[2])) - { - int bankno = std::atoi(argv[2]); - if(adl_setBank(myDevice, bankno) != 0) - { - printError(adl_errorString()); - return 1; - } - } - else - { - std::fprintf(stdout, "Loading custom bank file %s...", argv[2]); - std::fflush(stdout); - if(adl_openBankFile(myDevice, argv[2]) != 0) - { - std::fprintf(stdout, "FAILED!\n"); - std::fflush(stdout); - printError(adl_errorString()); - return 1; - } - std::fprintf(stdout, "OK!\n"); - std::fflush(stdout); - } - } - - if(argc >= 4) - { - if(adl_setNumCards(myDevice, std::atoi(argv[3])) != 0) - { - printError(adl_errorString()); - return 1; - } - std::fprintf(stdout, "Number of cards %s\n", argv[3]); - } - else - { - // 4 chips by default - if(adl_setNumCards(myDevice, 4) != 0) - { - printError(adl_errorString()); - return 1; - } - } - - if(argc >= 5) - { - if(adl_setNumFourOpsChn(myDevice, std::atoi(argv[4])) != 0) - { - printError(adl_errorString()); - return 1; - } - std::fprintf(stdout, "Number of four-ops %s\n", argv[4]); - } - - if(adl_openFile(myDevice, argv[1]) != 0) - { - printError(adl_errorString()); - return 2; - } - - signal(SIGINT, sighandler); - signal(SIGTERM, sighandler); - #ifndef _WIN32 - signal(SIGHUP, sighandler); - #endif - - if(!recordWave) - { - SDL_PauseAudio(0); - - while(!stop) - { - short buff[4096]; - size_t got = (size_t)adl_play(myDevice, 4096, buff); - if(got <= 0) - break; - - AudioBuffer_lock.Lock(); - size_t pos = AudioBuffer.size(); - AudioBuffer.resize(pos + got); - for(size_t p = 0; p < got; ++p) - AudioBuffer[pos + p] = buff[p]; - AudioBuffer_lock.Unlock(); - - const SDL_AudioSpec &spec = obtained; - while(AudioBuffer.size() > spec.samples + (spec.freq * 2) * OurHeadRoomLength) - { - SDL_Delay(1); - } - } - - SDL_CloseAudio(); - } - else - { - std::string wave_out = std::string(argv[1]) + ".wav"; - std::fprintf(stdout, "Recording WAV file %s...\n", wave_out.c_str()); - std::fflush(stdout); - - if(wave_open(spec.freq, wave_out.c_str()) == 0) - { - wave_enable_stereo(); - while(!stop) - { - short buff[4096]; - size_t got = (size_t)adl_play(myDevice, 4096, buff); - if(got <= 0) - break; - wave_write(buff, (long)got); - } - wave_close(); - - std::fprintf(stdout, "Completed!\n"); - std::fflush(stdout); - } - else - { - adl_close(myDevice); - return 1; - } - } - - adl_close(myDevice); - - return 0; -} - diff --git a/src/midiplay/wave_writer.c b/src/midiplay/wave_writer.c deleted file mode 100755 index 0bfaf68..0000000 --- a/src/midiplay/wave_writer.c +++ /dev/null @@ -1,170 +0,0 @@ -/* snes_spc 0.9.0. http://www.slack.net/~ant/ */ - -#include "wave_writer.h" - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> - -#ifdef _WIN32 -#include <windows.h> -#endif - -/* Copyright (C) 2003-2007 Shay Green. This module 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 2.1 of the License, or (at your option) any later version. This -module 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 this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -enum { buf_size = 32768 * 2 }; -enum { header_size = 0x2C }; - -typedef short sample_t; - -static unsigned char* buf; -static FILE* file; -static long sample_count_; -static long sample_rate_; -static long buf_pos; -static int chan_count; - -static void exit_with_error( const char* str ) -{ - fprintf(stderr, "WAVE Writer Error: %s\n", str ); - fflush(stderr); -} - -int wave_open( long sample_rate, const char* filename ) -{ - sample_count_ = 0; - sample_rate_ = sample_rate; - buf_pos = header_size; - chan_count = 1; - - buf = (unsigned char*) malloc( buf_size * sizeof *buf ); - if ( !buf ) - { - exit_with_error( "Out of memory" ); - return -1; - } - -#ifndef _WIN32 - file = fopen( filename, "wb" ); -#else - wchar_t widePath[MAX_PATH]; - int size = MultiByteToWideChar(CP_UTF8, 0, filename, strlen(filename), widePath, MAX_PATH); - widePath[size] = '\0'; - file = _wfopen( widePath, L"wb" ); -#endif - if (!file) - { - exit_with_error( "Couldn't open WAVE file for writing" ); - return -1; - } - - setvbuf( file, 0, _IOFBF, 32 * 1024L ); - return 0; -} - -void wave_enable_stereo( void ) -{ - chan_count = 2; -} - -static void flush_() -{ - if ( buf_pos && !fwrite( buf, (size_t)buf_pos, 1, file ) ) - exit_with_error( "Couldn't write WAVE data" ); - buf_pos = 0; -} - -void wave_write( short const* in, long remain ) -{ - sample_count_ += remain; - while ( remain ) - { - if ( buf_pos >= buf_size ) - flush_(); - - { - unsigned char* p = &buf [buf_pos]; - long n = (buf_size - (unsigned long)buf_pos) / sizeof (sample_t); - if ( n > remain ) - n = remain; - remain -= n; - - /* convert to LSB first format */ - while ( n-- ) - { - int s = *in++; - *p++ = (unsigned char) s & (0x00FF); - *p++ = (unsigned char) (s >> 8) & (0x00FF); - } - - buf_pos = p - buf; - assert( buf_pos <= buf_size ); - } - } -} - -long wave_sample_count( void ) -{ - return sample_count_; -} - -static void set_le32( void* p, unsigned long n ) -{ - ((unsigned char*) p) [0] = (unsigned char) n & (0xFF); - ((unsigned char*) p) [1] = (unsigned char) (n >> 8) & (0xFF); - ((unsigned char*) p) [2] = (unsigned char) (n >> 16) & (0xFF); - ((unsigned char*) p) [3] = (unsigned char) (n >> 24) & (0xFF); -} - -void wave_close( void ) -{ - if ( file ) - { - /* generate header */ - unsigned char h [header_size] = - { - 'R','I','F','F', - 0,0,0,0, /* length of rest of file */ - 'W','A','V','E', - 'f','m','t',' ', - 0x10,0,0,0, /* size of fmt chunk */ - 1,0, /* uncompressed format */ - 0,0, /* channel count */ - 0,0,0,0, /* sample rate */ - 0,0,0,0, /* bytes per second */ - 0,0, /* bytes per sample frame */ - 16,0, /* bits per sample */ - 'd','a','t','a', - 0,0,0,0, /* size of sample data */ - /* ... */ /* sample data */ - }; - long ds = sample_count_ * (long)sizeof (sample_t); - int frame_size = chan_count * (long)sizeof (sample_t); - - set_le32( h + 0x04, header_size - 8 + ds ); - h [0x16] = (unsigned char)chan_count; - set_le32( h + 0x18, (unsigned long)sample_rate_ ); - set_le32( h + 0x1C, (unsigned long)sample_rate_ * (unsigned long)frame_size ); - h [0x20] = (unsigned char)frame_size; - set_le32( h + 0x28, (unsigned long)ds ); - - flush_(); - - /* write header */ - fseek( file, 0, SEEK_SET ); - fwrite( h, header_size, 1, file ); - fclose( file ); - file = 0; - free( buf ); - buf = 0; - } -} diff --git a/src/midiplay/wave_writer.h b/src/midiplay/wave_writer.h deleted file mode 100755 index 6d49718..0000000 --- a/src/midiplay/wave_writer.h +++ /dev/null @@ -1,21 +0,0 @@ -/* WAVE sound file writer for recording 16-bit output during program development */ - -#pragma once -#ifndef WAVE_WRITER_H -#define WAVE_WRITER_H - -#ifdef __cplusplus - extern "C" { -#endif - -int wave_open( long sample_rate, const char* filename ); -void wave_enable_stereo( void ); -void wave_write( short const* in, long count ); -long wave_sample_count( void ); -void wave_close( void ); - -#ifdef __cplusplus - } -#endif - -#endif |