1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-25 16:15:53 +00:00

Merge pull request #279 from a740g/miniaudio-fixes

Miniaudio fixes
This commit is contained in:
Samuel Gomes 2023-01-09 06:53:03 +05:30 committed by GitHub
commit 9ce19d0405
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 6526 additions and 1030 deletions

View file

@ -287,7 +287,7 @@ ifneq ($(filter y,$(DEP_AUDIO_MINIAUDIO)),)
CXXFLAGS += -DDEPENDENCY_AUDIO_MINIAUDIO
QBLIB_NAME := $(addsuffix 1,$(QBLIB_NAME))
LICENSE_IN_USE += miniaudio libxmp-lite radv2 stbvorbis
LICENSE_IN_USE += miniaudio libxmp-lite radv2 stbvorbis hivelytracker
ifdef DEP_AUDIO_DECODE_MIDI
LICENSE_IN_USE += tinysoundfont tinymidiloader

View file

@ -86,6 +86,7 @@ void sub__sndrawdone(int32_t handle, int32_t passed);
double func__sndrawlen(int32_t handle, int32_t passed);
mem_block func__memsound(int32_t handle, int32_t targetChannel);
int32_t func__sndnew(int32_t frames, int32_t channels, int32_t bits);
void snd_init();
void snd_un_init();

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@ MINIAUDIO_REAL_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/audio/%.o,$(MIN
MINIAUDIO_STUB_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/audio/%.o,$(MINIAUDIO_STUB_SRCS))
ifdef DEP_AUDIO_MINIAUDIO
MINIAUDIO_OBJS := $(MINIAUDIO_REAL_OBJS) $(MA_VTABLES_OBJS) $(LIBXMP_LIB)
MINIAUDIO_OBJS := $(MINIAUDIO_REAL_OBJS) $(MA_VTABLES_OBJS) $(HIVELY_OBJS) $(LIBXMP_LIB)
ifdef DEP_AUDIO_DECODE_MIDI
MINIAUDIO_OBJS += $(MIDI_MA_VTABLES_OBJS)
@ -28,6 +28,6 @@ endif
# DEPENDENCY_CONSOLE_ONLY is added here to keep these .cpp files from including
# the FreeGLUT headers via `libqb.h`. Ideally this is fixed properly in the future.
$(PATH_INTERNAL_C)/parts/audio/%.o: $(PATH_INTERNAL_C)/parts/audio/%.cpp
$(CXX) $(CXXFLAGS) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@
$(CXX) -O2 $(CXXFLAGS) -DDEPENDENCY_CONSOLE_ONLY -Wall $< -c -o $@
CLEAN_LIST += $(MINIAUDIO_REAL_OBJS) $(MINIAUDIO_STUB_OBJS)

View file

@ -34,14 +34,22 @@ LIBXMP_OBJS += $(patsubst %.c,$(PATH_INTERNAL_C)/parts/audio/extras/libxmp-lite/
LIBXMP_LIB := $(PATH_INTERNAL_C)/parts/audio/extras/libxmp-lite.a
$(PATH_INTERNAL_C)/parts/audio/extras/libxmp-lite/%.o: $(PATH_INTERNAL_C)/parts/audio/extras/libxmp-lite/%.c
$(CC) $(CFLAGS) -Wall -DLIBXMP_CORE_PLAYER -DLIBXMP_NO_PROWIZARD -DLIBXMP_NO_DEPACKERS -DBUILDING_STATIC $< -c -o $@
$(CC) -O2 $(CFLAGS) -Wall -DLIBXMP_CORE_PLAYER -DLIBXMP_NO_PROWIZARD -DLIBXMP_NO_DEPACKERS -DBUILDING_STATIC $< -c -o $@
$(LIBXMP_LIB): $(LIBXMP_OBJS)
$(AR) rcs $@ $^
HIVELY_SRCS := hvl_replay.c
HIVELY_OBJS += $(patsubst %.c,$(PATH_INTERNAL_C)/parts/audio/extras/hivelytracker/%.o,$(HIVELY_SRCS))
$(PATH_INTERNAL_C)/parts/audio/extras/hivelytracker/%.o: $(PATH_INTERNAL_C)/parts/audio/extras/hivelytracker/%.c
$(CC) -O2 $(CFLAGS) -Wall $< -c -o $@
MA_VTABLES_SRCS := \
mod_ma_vtable.cpp \
radv2_ma_vtable.cpp
radv2_ma_vtable.cpp \
hively_ma_vtable.cpp
MA_VTABLES_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/audio/extras/%.o,$(MA_VTABLES_SRCS))
@ -78,5 +86,5 @@ $(PATH_INTERNAL_TEMP)/soundfont.o: $(PATH_INTERNAL_TEMP)/soundfont.sf2
endif
endif
CLEAN_LIST += $(LIBXMP_LIB) $(LIBXMP_OBJS) $(MA_VTABLES_OBJS) $(MIDI_MA_VTABLES_OBJS) $(MIDI_MA_VTABLES_STUB_OBJS)
CLEAN_LIST += $(LIBXMP_LIB) $(LIBXMP_OBJS) $(HIVELY_OBJS) $(MA_VTABLES_OBJS) $(MIDI_MA_VTABLES_OBJS) $(MIDI_MA_VTABLES_STUB_OBJS)

View file

@ -0,0 +1,528 @@
//--------------------------------------------------------------------------------------------------
// ___ ___ __ _ _ ___ ___ _ _ _ ___ _
// / _ \| _ ) / /| | || _ \ __| /_\ _ _ __| (_)___ | __|_ _ __ _(_)_ _ ___
// | (_) | _ \/ _ \_ _| _/ _| / _ \ || / _` | / _ \ | _|| ' \/ _` | | ' \/ -_)
// \__\_\___/\___/ |_||_| |___| /_/ \_\_,_\__,_|_\___/ |___|_||_\__, |_|_||_\___|
// |___/
//
// QB64-PE Audio Engine powered by miniaudio (https://miniaud.io/)
//
// This implements a data source that decodes Amiga AHX and HLV formats
//
// https://github.com/pete-gordon/hivelytracker (BSD 3-Clause)
//
// Copyright (c) 2022 Samuel Gomes
// https://github.com/a740g
//
//--------------------------------------------------------------------------------------------------
#include "../miniaudio.h"
#include "audio.h"
#include "filepath.h"
#include "hivelytracker/hvl_replay.h"
#include <cstring>
constexpr auto MAX_HIVELY_FRAMES = 10 * 60 * 50; // maximium *hively* frames before timeout
struct ma_hively {
// This part is for miniaudio
ma_data_source_base ds; /* The decoder can be used independently as a data source. */
ma_read_proc onRead;
ma_seek_proc onSeek;
ma_tell_proc onTell;
void *pReadSeekTellUserData;
ma_format format;
// This part is format specific
hvl_tune *player; // player context
ma_uint64 lengthInSampleFrames; // total length of the tune in sample frames
ma_int16 *buffer; // render buffer (16-bit stereo)
ma_uint64 bufferSamples; // total number of samples in the buffer
ma_uint64 bufferReadCursor; // where is the buffer read cursor (in samples)
};
static ma_result ma_hively_seek_to_pcm_frame(ma_hively *pmaHively, ma_uint64 frameIndex) {
if (pmaHively == NULL) {
return MA_INVALID_ARGS;
}
// We can only reset the player to the beginning
if (frameIndex == 0) {
if (!hvl_InitSubsong(pmaHively->player, 0))
return MA_INVALID_OPERATION;
pmaHively->player->ht_SongEndReached = 0;
return MA_SUCCESS;
}
return MA_INVALID_OPERATION; // Anything else is not seekable
}
static ma_result ma_hively_get_data_format(ma_hively *pmaHively, ma_format *pFormat, ma_uint32 *pChannels, ma_uint32 *pSampleRate, ma_channel *pChannelMap,
size_t channelMapCap) {
/* Defaults for safety. */
if (pFormat != NULL) {
*pFormat = ma_format_unknown;
}
if (pChannels != NULL) {
*pChannels = 0;
}
if (pSampleRate != NULL) {
*pSampleRate = 0;
}
if (pChannelMap != NULL) {
memset(pChannelMap, 0, sizeof(*pChannelMap) * channelMapCap);
}
if (pmaHively == NULL) {
return MA_INVALID_OPERATION;
}
if (pFormat != NULL) {
*pFormat = pmaHively->format;
}
if (pChannels != NULL) {
*pChannels = 2; // Stereo
}
if (pSampleRate != NULL) {
*pSampleRate = MA_DEFAULT_SAMPLE_RATE;
}
if (pChannelMap != NULL) {
ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, 2);
}
return MA_SUCCESS;
}
static ma_result ma_hively_read_pcm_frames(ma_hively *pmaHively, void *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead) {
if (pFramesRead != NULL) {
*pFramesRead = 0;
}
if (frameCount == 0) {
return MA_INVALID_ARGS;
}
if (pmaHively == NULL) {
return MA_INVALID_ARGS;
}
auto result = MA_SUCCESS; /* Must be initialized to MA_SUCCESS. */
ma_uint64 totalFramesRead = 0;
auto buffer = (ma_int16 *)pFramesOut;
if (pmaHively->bufferReadCursor >= pmaHively->bufferSamples) {
// We are out of samples so reset the cursor and render some
pmaHively->bufferReadCursor = 0;
hvl_DecodeFrame(pmaHively->player, (int8 *)pmaHively->buffer, ((int8 *)pmaHively->buffer) + 2, 4);
}
while (totalFramesRead < frameCount) {
if (pmaHively->bufferReadCursor >= pmaHively->bufferSamples) // break out of the loop if we finished the block
break;
// Left channel sample
*buffer = pmaHively->buffer[pmaHively->bufferReadCursor];
++buffer;
pmaHively->bufferReadCursor++;
// Right channel sample
*buffer = pmaHively->buffer[pmaHively->bufferReadCursor];
++buffer;
pmaHively->bufferReadCursor++;
++totalFramesRead;
}
// Are we done with the tune?
if (pmaHively->player->ht_SongEndReached)
result = MA_AT_END;
if (pFramesRead != NULL) {
*pFramesRead = totalFramesRead;
}
return result;
}
static ma_result ma_hively_get_cursor_in_pcm_frames(ma_hively *pmaHively, ma_uint64 *pCursor) {
if (!pCursor) {
return MA_INVALID_ARGS;
}
*pCursor = 0; /* Safety. */
if (!pmaHively) {
return MA_INVALID_ARGS;
}
return MA_NOT_IMPLEMENTED;
}
static ma_result ma_hively_get_length_in_pcm_frames(ma_hively *pmaHively, ma_uint64 *pLength) {
if (!pLength) {
return MA_INVALID_ARGS;
}
*pLength = 0; /* Safety. */
if (!pmaHively) {
return MA_INVALID_ARGS;
}
if (pmaHively->lengthInSampleFrames < 1) {
return MA_INVALID_FILE;
}
*pLength = pmaHively->lengthInSampleFrames;
return MA_SUCCESS;
}
static ma_result ma_hively_ds_read(ma_data_source *pDataSource, void *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead) {
return ma_hively_read_pcm_frames((ma_hively *)pDataSource, pFramesOut, frameCount, pFramesRead);
}
static ma_result ma_hively_ds_seek(ma_data_source *pDataSource, ma_uint64 frameIndex) {
return ma_hively_seek_to_pcm_frame((ma_hively *)pDataSource, frameIndex);
}
static ma_result ma_hively_ds_get_data_format(ma_data_source *pDataSource, ma_format *pFormat, ma_uint32 *pChannels, ma_uint32 *pSampleRate,
ma_channel *pChannelMap, size_t channelMapCap) {
return ma_hively_get_data_format((ma_hively *)pDataSource, pFormat, pChannels, pSampleRate, pChannelMap, channelMapCap);
}
static ma_result ma_hively_ds_get_cursor(ma_data_source *pDataSource, ma_uint64 *pCursor) {
return ma_hively_get_cursor_in_pcm_frames((ma_hively *)pDataSource, pCursor);
}
static ma_result ma_hively_ds_get_length(ma_data_source *pDataSource, ma_uint64 *pLength) {
return ma_hively_get_length_in_pcm_frames((ma_hively *)pDataSource, pLength);
}
/// @brief HivelyTracker data source vtable
static ma_data_source_vtable ma_data_source_vtable_hively = {
ma_hively_ds_read, // Decodes and returns multiple frames of audio
ma_hively_ds_seek, // Can only support seeking to position 0
ma_hively_ds_get_data_format, // Returns the audio format to miniaudio
ma_hively_ds_get_cursor, // Not supported
ma_hively_ds_get_length, // Returns the precalculated length
NULL, // onSetLooping: NOP
0 // flags: none
};
static int ma_hively_of_callback__read(void *pUserData, unsigned char *pBufferOut, int bytesToRead) {
ma_hively *pmaHively = (ma_hively *)pUserData;
ma_result result;
size_t bytesRead;
result = pmaHively->onRead(pmaHively->pReadSeekTellUserData, (void *)pBufferOut, bytesToRead, &bytesRead);
if (result != MA_SUCCESS) {
return -1;
}
return (int)bytesRead;
}
static int ma_hively_of_callback__seek(void *pUserData, ma_int64 offset, int whence) {
ma_hively *pmaHively = (ma_hively *)pUserData;
ma_result result;
ma_seek_origin origin;
if (whence == SEEK_SET) {
origin = ma_seek_origin_start;
} else if (whence == SEEK_END) {
origin = ma_seek_origin_end;
} else {
origin = ma_seek_origin_current;
}
result = pmaHively->onSeek(pmaHively->pReadSeekTellUserData, offset, origin);
if (result != MA_SUCCESS) {
return -1;
}
return 0;
}
static ma_int64 ma_hively_of_callback__tell(void *pUserData) {
ma_hively *pmaHively = (ma_hively *)pUserData;
ma_result result;
ma_int64 cursor;
if (pmaHively->onTell == NULL) {
return -1;
}
result = pmaHively->onTell(pmaHively->pReadSeekTellUserData, &cursor);
if (result != MA_SUCCESS) {
return -1;
}
return cursor;
}
static ma_result ma_hively_init_internal(const ma_decoding_backend_config *pConfig, ma_hively *pmaHively) {
ma_result result;
ma_data_source_config dataSourceConfig;
if (pmaHively == NULL) {
return MA_INVALID_ARGS;
}
memset(pmaHively, 0, sizeof(*pmaHively));
pmaHively->format = ma_format::ma_format_s16; // We'll render 16-bit signed samples
if (pConfig != NULL && pConfig->preferredFormat == ma_format::ma_format_s16) {
pmaHively->format = pConfig->preferredFormat;
} else {
/* Getting here means something other than s16 was specified. Just leave this unset to use the default format. */
}
dataSourceConfig = ma_data_source_config_init();
dataSourceConfig.vtable = &ma_data_source_vtable_hively;
result = ma_data_source_init(&dataSourceConfig, &pmaHively->ds);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the base data source. */
}
return MA_SUCCESS;
}
// This help us calculate the total frame size of the tune
// Note that this must be called before rendering the tune as it actually "plays" it to a dummy buffer to calulate the length
static ma_uint64 ma_hively_get_length_in_pcm_frames_internal(ma_hively *pmaHively) {
ma_uint64 totalFramesRead = 0;
auto frame = 0;
while (frame < MAX_HIVELY_FRAMES) {
if (pmaHively->player->ht_SongEndReached)
break;
hvl_DecodeFrame(pmaHively->player, (int8 *)pmaHively->buffer, ((int8 *)pmaHively->buffer) + 2, 4);
totalFramesRead += pmaHively->bufferSamples >> 1; // divide by 2 for 2 channels
++frame;
}
// Reset playback position
hvl_InitSubsong(pmaHively->player, 0);
pmaHively->player->ht_SongEndReached = 0;
return totalFramesRead; // Return the total frames rendered
}
static ma_result ma_hively_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void *pReadSeekTellUserData,
const ma_decoding_backend_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks, ma_hively *pmaHively) {
ma_result result;
(void)pAllocationCallbacks; /* Can't seem to find a way to configure memory allocations in libopus. */
result = ma_hively_init_internal(pConfig, pmaHively);
if (result != MA_SUCCESS) {
return result;
}
if (onRead == NULL || onSeek == NULL) {
return MA_INVALID_ARGS; /* onRead and onSeek are mandatory. */
}
pmaHively->onRead = onRead;
pmaHively->onSeek = onSeek;
pmaHively->onTell = onTell;
pmaHively->pReadSeekTellUserData = pReadSeekTellUserData;
// Find the size of the file
if (ma_hively_of_callback__seek(pmaHively, 0, SEEK_END) != 0) {
return MA_BAD_SEEK;
}
// Calculate the length
ma_int64 file_size = ma_hively_of_callback__tell(pmaHively);
if (file_size < 1) {
return MA_INVALID_FILE;
}
// Seek to the beginning of the file
if (ma_hively_of_callback__seek(pmaHively, 0, SEEK_SET) != 0) {
return MA_BAD_SEEK;
}
// Allocate some memory for the tune
ma_uint8 *tune = new ma_uint8[file_size];
if (tune == nullptr) {
return MA_OUT_OF_MEMORY;
}
// Read the file
if (ma_hively_of_callback__read(pmaHively, tune, (int)file_size) < 1) {
delete[] tune;
return MA_IO_ERROR;
}
hvl_InitReplayer(); // we'll initialize the re-player here
// Ok, we have the tune in memory, now loads it
pmaHively->player = hvl_ParseTune(tune, file_size, MA_DEFAULT_SAMPLE_RATE, 3);
if (!pmaHively->player || !hvl_InitSubsong(pmaHively->player, 0)) {
if (pmaHively->player)
hvl_FreeTune(pmaHively->player);
pmaHively->player = nullptr;
}
// Free the memory now that we don't need it anymore
delete[] tune;
if (pmaHively->player == nullptr) {
// This means our loader failed
return MA_INVALID_FILE;
}
// Calculate the buffer size and then allocate memory
pmaHively->bufferSamples = (MA_DEFAULT_SAMPLE_RATE * 2) / 50;
pmaHively->buffer = new ma_int16[pmaHively->bufferSamples];
if (!pmaHively->buffer) {
hvl_FreeTune(pmaHively->player);
pmaHively->player = nullptr;
return MA_OUT_OF_MEMORY;
}
// Calculate the sample frames
pmaHively->lengthInSampleFrames = ma_hively_get_length_in_pcm_frames_internal(pmaHively);
return MA_SUCCESS;
}
static ma_result ma_hively_init_file(const char *pFilePath, const ma_decoding_backend_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks,
ma_hively *pmaHively) {
ma_result result;
(void)pAllocationCallbacks; /* Can't seem to find a way to configure memory allocations in libopus. */
result = ma_hively_init_internal(pConfig, pmaHively);
if (result != MA_SUCCESS) {
return result;
}
// Check the file extension
if (filepath_has_extension(pFilePath, "hvl") || filepath_has_extension(pFilePath, "ahx")) {
hvl_InitReplayer(); // we'll initialize the re-player here
pmaHively->player = hvl_LoadTune(pFilePath, MA_DEFAULT_SAMPLE_RATE, 3);
if (!pmaHively->player || !hvl_InitSubsong(pmaHively->player, 0)) {
if (pmaHively->player)
hvl_FreeTune(pmaHively->player);
pmaHively->player = nullptr;
return MA_INVALID_FILE;
}
// Calculate the buffer size and then allocate memory
pmaHively->bufferSamples = (MA_DEFAULT_SAMPLE_RATE * 2) / 50;
pmaHively->buffer = new ma_int16[pmaHively->bufferSamples];
if (!pmaHively->buffer) {
hvl_FreeTune(pmaHively->player);
pmaHively->player = nullptr;
return MA_OUT_OF_MEMORY;
}
} else {
return MA_INVALID_FILE;
}
// Calculate the sample frames
pmaHively->lengthInSampleFrames = ma_hively_get_length_in_pcm_frames_internal(pmaHively);
return MA_SUCCESS;
}
static void ma_hively_uninit(ma_hively *pmaHively, const ma_allocation_callbacks *pAllocationCallbacks) {
if (pmaHively == NULL) {
return;
}
(void)pAllocationCallbacks;
// Free all resources
pmaHively->lengthInSampleFrames = 0;
pmaHively->bufferSamples = 0;
pmaHively->bufferReadCursor = 0;
hvl_FreeTune(pmaHively->player);
pmaHively->player = nullptr;
delete[] pmaHively->buffer;
pmaHively->buffer = nullptr;
ma_data_source_uninit(&pmaHively->ds);
}
static ma_result ma_decoding_backend_init__hively(void *pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void *pReadSeekTellUserData,
const ma_decoding_backend_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks,
ma_data_source **ppBackend) {
ma_result result;
ma_hively *pmaHively;
(void)pUserData;
pmaHively = (ma_hively *)ma_malloc(sizeof(ma_hively), pAllocationCallbacks);
if (pmaHively == NULL) {
return MA_OUT_OF_MEMORY;
}
result = ma_hively_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pmaHively);
if (result != MA_SUCCESS) {
ma_free(pmaHively, pAllocationCallbacks);
return result;
}
*ppBackend = pmaHively;
return MA_SUCCESS;
}
static ma_result ma_decoding_backend_init_file__hively(void *pUserData, const char *pFilePath, const ma_decoding_backend_config *pConfig,
const ma_allocation_callbacks *pAllocationCallbacks, ma_data_source **ppBackend) {
ma_result result;
ma_hively *pmaHively;
(void)pUserData;
pmaHively = (ma_hively *)ma_malloc(sizeof(ma_hively), pAllocationCallbacks);
if (pmaHively == NULL) {
return MA_OUT_OF_MEMORY;
}
result = ma_hively_init_file(pFilePath, pConfig, pAllocationCallbacks, pmaHively);
if (result != MA_SUCCESS) {
ma_free(pmaHively, pAllocationCallbacks);
return result;
}
*ppBackend = pmaHively;
return MA_SUCCESS;
}
static void ma_decoding_backend_uninit__hively(void *pUserData, ma_data_source *pBackend, const ma_allocation_callbacks *pAllocationCallbacks) {
ma_hively *pmaHively = (ma_hively *)pBackend;
(void)pUserData;
ma_hively_uninit(pmaHively, pAllocationCallbacks);
ma_free(pmaHively, pAllocationCallbacks);
}
ma_decoding_backend_vtable ma_vtable_hively = {ma_decoding_backend_init__hively, ma_decoding_backend_init_file__hively, NULL, /* onInitFileW() */
NULL, /* onInitMemory() */
ma_decoding_backend_uninit__hively};
//-----------------------------------------------------------------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,259 @@
//----------------------------------------------------------------------------------------------------
// ___ ___ __ _ _ ___ ___ _ _ _ ___ _
// / _ \| _ ) / /| | || _ \ __| /_\ _ _ __| (_)___ | __|_ _ __ _(_)_ _ ___
// | (_) | _ \/ _ \_ _| _/ _| / _ \ || / _` | / _ \ | _|| ' \/ _` | | ' \/ -_)
// \__\_\___/\___/ |_||_| |___| /_/ \_\_,_\__,_|_\___/ |___|_||_\__, |_|_||_\___|
// |___/
//
// QB64-PE Audio Engine powered by miniaudio (https://miniaud.io/)
//
// hvl_replay.c + hvl_replay.h is a modified AHX & HVL replayer from
// https://github.com/pete-gordon/hivelytracker (BSD 3-Clause License)
//
// Some modifications were required to make this suitable for QB64-PE. The points below lists the
// changes that were made. We may need to redo these if we need to reconstruct these files from
// newer versions of the HivelyTracker replayer code.
//
// 1. Use the replayer code in 'Replayer_Windows'
// 2. Comment out all printfs from hvl_replay.c and hvl_tables.c
// 3. hvl_tables.c and hvl_replay.c can be amalgamated like in 'hvl2wav'
// 4. hvl_tables.h and hvl_replay.h can be amalgamated iike in 'hvl2wav'
// 5. Add 'extern "C"' block around the function declarations in hvl_replay.h
// 6. Change 'typedef char int8' to 'typedef signed char int8' in hvl_replay.h
//
//-----------------------------------------------------------------------------------------------------
#pragma once
typedef signed char int8;
typedef unsigned char uint8;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned int uint32;
typedef double float64;
typedef char TEXT;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
// Woohoo!
#define MAX_CHANNELS 16
// Some handy constants. Thanks eightbitbubsy.
#define AMIGA_PAL_XTAL 28375160
#define AMIGA_NTSC_XTAL 28636360
#define AMIGA_CPU_PAL_CLK ((AMIGA_PAL_XTAL / 4))
#define AMIGA_CPU_NTSC_CLK ((AMIGA_NTSC_XTAL / 4))
#define AMIGA_CIA_PAL_CLK ((AMIGA_CPU_PAL_CLK / 10))
#define AMIGA_CIA_NTSC_CLK ((AMIGA_CPU_NTSC_CLK / 10))
#define AMIGA_PAULA_PAL_CLK ((AMIGA_CPU_PAL_CLK / 2))
#define AMIGA_PAULA_NTSC_CLK ((AMIGA_CPU_NTSC_CLK / 2))
#define Period2Freq(period) ((AMIGA_PAULA_PAL_CLK * 65536.f) / (period))
#ifdef __cplusplus
extern "C" {
#endif
struct hvl_envelope {
int16 aFrames, aVolume;
int16 dFrames, dVolume;
int16 sFrames;
int16 rFrames, rVolume;
int16 pad;
};
struct hvl_plsentry {
uint8 ple_Note;
uint8 ple_Waveform;
int16 ple_Fixed;
int8 ple_FX[2];
int8 ple_FXParam[2];
};
struct hvl_plist {
int16 pls_Speed;
int16 pls_Length;
struct hvl_plsentry *pls_Entries;
};
struct hvl_instrument {
TEXT ins_Name[128];
uint8 ins_Volume;
uint8 ins_WaveLength;
uint8 ins_FilterLowerLimit;
uint8 ins_FilterUpperLimit;
uint8 ins_FilterSpeed;
uint8 ins_SquareLowerLimit;
uint8 ins_SquareUpperLimit;
uint8 ins_SquareSpeed;
uint8 ins_VibratoDelay;
uint8 ins_VibratoSpeed;
uint8 ins_VibratoDepth;
uint8 ins_HardCutRelease;
uint8 ins_HardCutReleaseFrames;
struct hvl_envelope ins_Envelope;
struct hvl_plist ins_PList;
};
struct hvl_position {
uint8 pos_Track[MAX_CHANNELS];
int8 pos_Transpose[MAX_CHANNELS];
};
struct hvl_step {
uint8 stp_Note;
uint8 stp_Instrument;
uint8 stp_FX;
uint8 stp_FXParam;
uint8 stp_FXb;
uint8 stp_FXbParam;
};
struct hvl_voice {
int16 vc_Track;
int16 vc_NextTrack;
int16 vc_Transpose;
int16 vc_NextTranspose;
int16 vc_OverrideTranspose; // 1.5
int32 vc_ADSRVolume;
struct hvl_envelope vc_ADSR;
struct hvl_instrument *vc_Instrument;
uint32 vc_SamplePos;
uint32 vc_Delta;
uint16 vc_InstrPeriod;
uint16 vc_TrackPeriod;
uint16 vc_VibratoPeriod;
uint16 vc_WaveLength;
int16 vc_NoteMaxVolume;
uint16 vc_PerfSubVolume;
uint8 vc_NewWaveform;
uint8 vc_Waveform;
uint8 vc_PlantPeriod;
uint8 vc_VoiceVolume;
uint8 vc_PlantSquare;
uint8 vc_IgnoreSquare;
uint8 vc_FixedNote;
int16 vc_VolumeSlideUp;
int16 vc_VolumeSlideDown;
int16 vc_HardCut;
uint8 vc_HardCutRelease;
int16 vc_HardCutReleaseF;
uint8 vc_PeriodSlideOn;
int16 vc_PeriodSlideSpeed;
int16 vc_PeriodSlidePeriod;
int16 vc_PeriodSlideLimit;
int16 vc_PeriodSlideWithLimit;
int16 vc_PeriodPerfSlideSpeed;
int16 vc_PeriodPerfSlidePeriod;
uint8 vc_PeriodPerfSlideOn;
int16 vc_VibratoDelay;
int16 vc_VibratoSpeed;
int16 vc_VibratoCurrent;
int16 vc_VibratoDepth;
int16 vc_SquareOn;
int16 vc_SquareInit;
int16 vc_SquareWait;
int16 vc_SquareLowerLimit;
int16 vc_SquareUpperLimit;
int16 vc_SquarePos;
int16 vc_SquareSign;
int16 vc_SquareSlidingIn;
int16 vc_SquareReverse;
uint8 vc_FilterOn;
uint8 vc_FilterInit;
int16 vc_FilterWait;
int16 vc_FilterSpeed;
int16 vc_FilterUpperLimit;
int16 vc_FilterLowerLimit;
int16 vc_FilterPos;
int16 vc_FilterSign;
int16 vc_FilterSlidingIn;
int16 vc_IgnoreFilter;
int16 vc_PerfCurrent;
int16 vc_PerfSpeed;
int16 vc_PerfWait;
struct hvl_plist *vc_PerfList;
const int8 *vc_AudioPointer;
const int8 *vc_AudioSource;
uint8 vc_NoteDelayOn;
uint8 vc_NoteCutOn;
int16 vc_NoteDelayWait;
int16 vc_NoteCutWait;
int16 vc_AudioPeriod;
int16 vc_AudioVolume;
int32 vc_WNRandom;
const int8 *vc_MixSource;
int8 vc_SquareTempBuffer[0x80];
int8 vc_VoiceBuffer[0x282 * 4];
uint8 vc_VoiceNum;
uint8 vc_TrackMasterVolume;
uint8 vc_TrackOn;
int16 vc_VoicePeriod;
uint32 vc_Pan;
uint32 vc_SetPan; // New for 1.4
uint32 vc_PanMultLeft;
uint32 vc_PanMultRight;
uint32 vc_RingSamplePos;
uint32 vc_RingDelta;
const int8 *vc_RingMixSource;
uint8 vc_RingPlantPeriod;
int16 vc_RingInstrPeriod;
int16 vc_RingBasePeriod;
int16 vc_RingAudioPeriod;
const int8 *vc_RingAudioSource;
uint8 vc_RingNewWaveform;
uint8 vc_RingWaveform;
uint8 vc_RingFixedPeriod;
int8 vc_RingVoiceBuffer[0x282 * 4];
};
struct hvl_tune {
TEXT ht_Name[128];
uint16 ht_SongNum;
uint32 ht_Frequency;
float64 ht_FreqF;
const int8 *ht_WaveformTab[MAX_CHANNELS];
uint16 ht_Restart;
uint16 ht_PositionNr;
uint8 ht_SpeedMultiplier;
uint8 ht_TrackLength;
uint8 ht_TrackNr;
uint8 ht_InstrumentNr;
uint8 ht_SubsongNr;
uint16 ht_PosJump;
uint32 ht_PlayingTime;
int16 ht_Tempo;
int16 ht_PosNr;
uint16 ht_StepWaitFrames;
int16 ht_NoteNr;
uint16 ht_PosJumpNote;
uint8 ht_GetNewPosition;
uint8 ht_PatternBreak;
uint8 ht_SongEndReached;
uint8 ht_Stereo;
uint16 *ht_Subsongs;
uint16 ht_Channels;
struct hvl_position *ht_Positions;
struct hvl_step ht_Tracks[256][64];
struct hvl_instrument *ht_Instruments;
struct hvl_voice ht_Voices[MAX_CHANNELS];
int32 ht_defstereo;
int32 ht_defpanleft;
int32 ht_defpanright;
int32 ht_mixgain;
uint8 ht_Version;
};
void hvl_DecodeFrame(struct hvl_tune *ht, int8 *buf1, int8 *buf2, int32 bufmod);
void hvl_InitReplayer(void);
BOOL hvl_InitSubsong(struct hvl_tune *ht, uint32 nr);
struct hvl_tune *hvl_LoadTune(const TEXT *name, uint32 freq, uint32 defstereo);
struct hvl_tune *hvl_ParseTune(const uint8 *buf, uint32 buflen, uint32 freq, uint32 defstereo);
void hvl_FreeTune(struct hvl_tune *ht);
#ifdef __cplusplus
}
#endif

View file

@ -6,5 +6,6 @@
extern ma_decoding_backend_vtable ma_vtable_midi;
extern ma_decoding_backend_vtable ma_vtable_modplay;
extern ma_decoding_backend_vtable ma_vtable_radv2;
extern ma_decoding_backend_vtable ma_vtable_hively;
#endif

File diff suppressed because it is too large Load diff

View file

@ -12,51 +12,41 @@
//
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// HEADER FILES
//-----------------------------------------------------------------------------------------------------
// Enable Ogg Vorbis decoding
#define STB_VORBIS_HEADER_ONLY
#include "extras/stb_vorbis.c"
// PulseAudio has serious stuttering issues in ChromeOS Linux (Crostini) and possibly others
// This may be due to this - https://github.com/mackron/miniaudio/issues/427
// And https://wiki.archlinux.org/title/PulseAudio/Troubleshooting#Glitches,_skips_or_crackling
// We'll have to look at this closely later. If this is fixed, then remove this define from here & audio.cpp
#define MA_NO_PULSEAUDIO
// The main miniaudio header
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
// The stb_vorbis implementation must come after the implementation of miniaudio
#undef STB_VORBIS_HEADER_ONLY
#include "extras/stb_vorbis.c"
#include "extras/vtables.h"
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// GLOBAL VARIABLES
//-----------------------------------------------------------------------------------------------------
// Add custom backend (format) vtables here
// The order in the array defines the order of priority
// The vtables will be passed in to the resource manager config
// ma_vtable_modplay should be the last one because libxmp supports 15-channel MODs which does not have any signatures
// This can lead to incorrect detection
static ma_decoding_backend_vtable *maCustomBackendVTables[] = {
&ma_vtable_radv2,
&ma_vtable_hively,
&ma_vtable_midi,
&ma_vtable_modplay,
};
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// FUNCTIONS
//-----------------------------------------------------------------------------------------------------
/// <summary>
/// This simply attaches the format decode VTables array to ma_resource_manager_config
/// </summary>
/// <param name="maResourceManagerConfig">Pointer to a miniaudio resource manager config object. This cannot be NULL</param>
/// @brief This simply attaches the format decode VTables array to ma_resource_manager_config
/// @param maDecoderConfig Pointer to a miniaudio resource manager config object. This cannot be NULL
void AudioEngineAttachCustomBackendVTables(ma_resource_manager_config *maResourceManagerConfig) {
// Attach the VTable
maResourceManagerConfig->ppCustomDecodingBackendVTables = maCustomBackendVTables;
maResourceManagerConfig->customDecodingBackendCount = ma_countof(maCustomBackendVTables);
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
/// @brief This simply attaches the format decode VTables array to ma_decoder_config
/// @param maDecoderConfig Pointer to a miniaudio decoder config object. This cannot be NULL
void AudioEngineAttachCustomBackendVTables(ma_decoder_config *maDecoderConfig) {
// Attach the VTable
maDecoderConfig->ppCustomBackendVTables = maCustomBackendVTables;
maDecoderConfig->customBackendCount = ma_countof(maCustomBackendVTables);
}

View file

@ -0,0 +1,32 @@
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -2058,6 +2058,19 @@ id.arg = MKL$(ULONGTYPE - ISPOINTER)
id.hr_syntax = "_SNDCLOSE handle&"
regid
' a740g: Feature request #28
clearid
id.n = qb64prefix$ + "SndNew" ' Name in CaMeL case
id.Dependency = DEPENDENCY_AUDIO_OUT ' QB64-PE library dependency
id.subfunc = 1 ' 1 = function, 2 = sub
id.callname = "func__sndnew" ' C/C++ function name
id.args = 3 ' number of arguments "passed"
id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) ' arguments & types
id.ret = LONGTYPE - ISPOINTER ' return type for functions
id.hr_syntax = "_SNDNEW(frames&, channels&, bits&)" ' syntax help
regid
' a740g: Feature request #28
clearid
id.n = "Input"
id.musthave = "$"

View file

@ -6,5 +6,5 @@ listOfKeywords$ = listOfKeywords$ + "_GLPOPATTRIB@_GLPOPCLIENTATTRIB@_GLPOPMATRI
listOfKeywords$ = listOfKeywords$ + "_SOFTWARE@_SQUAREPIXELS@_STRETCH@_ALLOWFULLSCREEN@_ALL@_ECHO@_INSTRREV@_TRIM$@_ACCEPTFILEDROP@_FINISHDROP@_TOTALDROPPEDFILES@_DROPPEDFILE@_DROPPEDFILE$@_SHR@_SHL@_ROR@_ROL@" ' a740g: added ROR & ROL
listOfKeywords$ = listOfKeywords$ + "_DEFLATE$@_INFLATE$@_READBIT@_RESETBIT@_SETBIT@_TOGGLEBIT@$ASSERTS@_ASSERT@_CAPSLOCK@_NUMLOCK@_SCROLLLOCK@_TOGGLE@_CONSOLEFONT@_CONSOLECURSOR@_CONSOLEINPUT@_CINP@$NOPREFIX@$COLOR@$DEBUG@_ENVIRONCOUNT@$UNSTABLE@$MIDISOUNDFONT@"
listOfKeywords$ = listOfKeywords$ + "_NOTIFYPOPUP@_MESSAGEBOX@_INPUTBOX$@_SELECTFOLDERDIALOG$@_COLORCHOOSERDIALOG@_OPENFILEDIALOG$@_SAVEFILEDIALOG$@" ' a740g: added common dialog keywords
listOfKeywords$ = listOfKeywords$ + "_STATUSCODE@" ' a740g: added common dialog keywords
listOfKeywords$ = listOfKeywords$ + "_STATUSCODE@_SNDNEW@"

View file

@ -0,0 +1,76 @@
$Console:Only
Option _Explicit
Option _ExplicitArray
Dim h As Long: h = _SndNew(1024, 2, 32)
Print "Handle ="; h
Dim m As _MEM: m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(0, 2, 32)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(1024, 0, 32)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(1024, 1, 0)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(1024, -10, 16)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(1024, 1, -32)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
h = _SndNew(-1024, 1, 16)
Print "Handle ="; h
m = _MemSound(h, 0)
Print "Size ="; m.SIZE
Print "Type ="; m.TYPE
Print "Element Size ="; m.ELEMENTSIZE
Print "Sound ="; m.SOUND
Print
_SndClose h
System

View file

@ -0,0 +1,42 @@
Handle = 1
Size = 8192
Type = 260
Element Size = 8
Sound = 1
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0
Handle = 0
Size = 0
Type = 0
Element Size = 0
Sound = 0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
Size = 42018
Handle = 1
Length = 21.10694

View file

@ -218,6 +218,38 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
License of FreeGLUT:
Freeglut Copyright

View file

@ -217,3 +217,35 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -218,6 +218,38 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
License of FreeGLUT:
Freeglut Copyright

View file

@ -218,6 +218,38 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
License of TinySoundFont:
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)

View file

@ -218,6 +218,38 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
License of TinySoundFont:
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)

View file

@ -218,6 +218,38 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
License of HivelyTracker:
BSD 3-Clause License
Copyright (c) 2006-2018, Pete Gordon
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
License of TinySoundFont:
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)