mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-07 15:20:18 +00:00
commit
9ce19d0405
24 changed files with 6526 additions and 1030 deletions
2
Makefile
2
Makefile
|
@ -287,7 +287,7 @@ ifneq ($(filter y,$(DEP_AUDIO_MINIAUDIO)),)
|
||||||
CXXFLAGS += -DDEPENDENCY_AUDIO_MINIAUDIO
|
CXXFLAGS += -DDEPENDENCY_AUDIO_MINIAUDIO
|
||||||
QBLIB_NAME := $(addsuffix 1,$(QBLIB_NAME))
|
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
|
ifdef DEP_AUDIO_DECODE_MIDI
|
||||||
LICENSE_IN_USE += tinysoundfont tinymidiloader
|
LICENSE_IN_USE += tinysoundfont tinymidiloader
|
||||||
|
|
|
@ -86,6 +86,7 @@ void sub__sndrawdone(int32_t handle, int32_t passed);
|
||||||
double func__sndrawlen(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);
|
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_init();
|
||||||
void snd_un_init();
|
void snd_un_init();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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))
|
MINIAUDIO_STUB_OBJS := $(patsubst %.cpp,$(PATH_INTERNAL_C)/parts/audio/%.o,$(MINIAUDIO_STUB_SRCS))
|
||||||
|
|
||||||
ifdef DEP_AUDIO_MINIAUDIO
|
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
|
ifdef DEP_AUDIO_DECODE_MIDI
|
||||||
MINIAUDIO_OBJS += $(MIDI_MA_VTABLES_OBJS)
|
MINIAUDIO_OBJS += $(MIDI_MA_VTABLES_OBJS)
|
||||||
|
@ -28,6 +28,6 @@ endif
|
||||||
# DEPENDENCY_CONSOLE_ONLY is added here to keep these .cpp files from including
|
# 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.
|
# 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
|
$(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)
|
CLEAN_LIST += $(MINIAUDIO_REAL_OBJS) $(MINIAUDIO_STUB_OBJS)
|
||||||
|
|
|
@ -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
|
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
|
$(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)
|
$(LIBXMP_LIB): $(LIBXMP_OBJS)
|
||||||
$(AR) rcs $@ $^
|
$(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 := \
|
MA_VTABLES_SRCS := \
|
||||||
mod_ma_vtable.cpp \
|
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))
|
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
|
||||||
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)
|
||||||
|
|
||||||
|
|
528
internal/c/parts/audio/extras/hively_ma_vtable.cpp
Normal file
528
internal/c/parts/audio/extras/hively_ma_vtable.cpp
Normal 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};
|
||||||
|
//-----------------------------------------------------------------------------------------------------
|
2048
internal/c/parts/audio/extras/hivelytracker/hvl_replay.c
Normal file
2048
internal/c/parts/audio/extras/hivelytracker/hvl_replay.c
Normal file
File diff suppressed because it is too large
Load diff
259
internal/c/parts/audio/extras/hivelytracker/hvl_replay.h
Normal file
259
internal/c/parts/audio/extras/hivelytracker/hvl_replay.h
Normal 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
|
|
@ -6,5 +6,6 @@
|
||||||
extern ma_decoding_backend_vtable ma_vtable_midi;
|
extern ma_decoding_backend_vtable ma_vtable_midi;
|
||||||
extern ma_decoding_backend_vtable ma_vtable_modplay;
|
extern ma_decoding_backend_vtable ma_vtable_modplay;
|
||||||
extern ma_decoding_backend_vtable ma_vtable_radv2;
|
extern ma_decoding_backend_vtable ma_vtable_radv2;
|
||||||
|
extern ma_decoding_backend_vtable ma_vtable_hively;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,51 +12,41 @@
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
// HEADER FILES
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
// Enable Ogg Vorbis decoding
|
// Enable Ogg Vorbis decoding
|
||||||
#define STB_VORBIS_HEADER_ONLY
|
#define STB_VORBIS_HEADER_ONLY
|
||||||
#include "extras/stb_vorbis.c"
|
#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
|
// The main miniaudio header
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
// The stb_vorbis implementation must come after the implementation of miniaudio
|
// The stb_vorbis implementation must come after the implementation of miniaudio
|
||||||
#undef STB_VORBIS_HEADER_ONLY
|
#undef STB_VORBIS_HEADER_ONLY
|
||||||
#include "extras/stb_vorbis.c"
|
#include "extras/stb_vorbis.c"
|
||||||
|
|
||||||
#include "extras/vtables.h"
|
#include "extras/vtables.h"
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
// GLOBAL VARIABLES
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
// Add custom backend (format) vtables here
|
// Add custom backend (format) vtables here
|
||||||
// The order in the array defines the order of priority
|
// The order in the array defines the order of priority
|
||||||
// The vtables will be passed in to the resource manager config
|
// 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[] = {
|
static ma_decoding_backend_vtable *maCustomBackendVTables[] = {
|
||||||
&ma_vtable_radv2,
|
&ma_vtable_radv2,
|
||||||
|
&ma_vtable_hively,
|
||||||
&ma_vtable_midi,
|
&ma_vtable_midi,
|
||||||
&ma_vtable_modplay,
|
&ma_vtable_modplay,
|
||||||
};
|
};
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
/// @brief This simply attaches the format decode VTables array to ma_resource_manager_config
|
||||||
// FUNCTIONS
|
/// @param maDecoderConfig Pointer to a miniaudio resource manager config object. This cannot be NULL
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
/// <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>
|
|
||||||
void AudioEngineAttachCustomBackendVTables(ma_resource_manager_config *maResourceManagerConfig) {
|
void AudioEngineAttachCustomBackendVTables(ma_resource_manager_config *maResourceManagerConfig) {
|
||||||
// Attach the VTable
|
// Attach the VTable
|
||||||
maResourceManagerConfig->ppCustomDecodingBackendVTables = maCustomBackendVTables;
|
maResourceManagerConfig->ppCustomDecodingBackendVTables = maCustomBackendVTables;
|
||||||
maResourceManagerConfig->customDecodingBackendCount = ma_countof(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);
|
||||||
|
}
|
||||||
|
|
32
licenses/license_hivelytracker.txt
Normal file
32
licenses/license_hivelytracker.txt
Normal 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.
|
|
@ -2058,6 +2058,19 @@ id.arg = MKL$(ULONGTYPE - ISPOINTER)
|
||||||
id.hr_syntax = "_SNDCLOSE handle&"
|
id.hr_syntax = "_SNDCLOSE handle&"
|
||||||
regid
|
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
|
clearid
|
||||||
id.n = "Input"
|
id.n = "Input"
|
||||||
id.musthave = "$"
|
id.musthave = "$"
|
||||||
|
|
|
@ -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$ + "_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$ + "_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$ + "_NOTIFYPOPUP@_MESSAGEBOX@_INPUTBOX$@_SELECTFOLDERDIALOG$@_COLORCHOOSERDIALOG@_OPENFILEDIALOG$@_SAVEFILEDIALOG$@" ' a740g: added common dialog keywords
|
||||||
listOfKeywords$ = listOfKeywords$ + "_STATUSCODE@" ' a740g: added common dialog keywords
|
listOfKeywords$ = listOfKeywords$ + "_STATUSCODE@_SNDNEW@"
|
||||||
|
|
||||||
|
|
76
tests/compile_tests/audio_mem_test/newsound_test.bas
Normal file
76
tests/compile_tests/audio_mem_test/newsound_test.bas
Normal 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
|
||||||
|
|
42
tests/compile_tests/audio_mem_test/newsound_test.output
Normal file
42
tests/compile_tests/audio_mem_test/newsound_test.output
Normal 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
|
||||||
|
|
1311
tests/compile_tests/audio_mem_test/sndopen_mem_test.bas
Normal file
1311
tests/compile_tests/audio_mem_test/sndopen_mem_test.bas
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,3 @@
|
||||||
|
Size = 42018
|
||||||
|
Handle = 1
|
||||||
|
Length = 21.10694
|
|
@ -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
|
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.
|
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:
|
License of FreeGLUT:
|
||||||
|
|
||||||
Freeglut Copyright
|
Freeglut Copyright
|
||||||
|
|
|
@ -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
|
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
|
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.
|
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.
|
||||||
|
|
|
@ -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
|
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.
|
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:
|
License of FreeGLUT:
|
||||||
|
|
||||||
Freeglut Copyright
|
Freeglut Copyright
|
||||||
|
|
|
@ -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
|
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.
|
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:
|
License of TinySoundFont:
|
||||||
|
|
||||||
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
||||||
|
|
|
@ -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
|
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.
|
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:
|
License of TinySoundFont:
|
||||||
|
|
||||||
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
||||||
|
|
|
@ -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
|
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.
|
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:
|
License of TinySoundFont:
|
||||||
|
|
||||||
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
Copyright (C) 2017-2018 Bernhard Schelling (Based on SFZero, Copyright (C) 2012 Steve Folta, https://github.com/stevefolta/SFZero)
|
||||||
|
|
Loading…
Reference in a new issue