@@ -211,19 +211,12 @@ endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Check for optional libs (required by internal plugins) | # Check for optional libs (required by internal plugins) | ||||
HAVE_AF_DEPS = $(shell pkg-config --exists sndfile && echo true) | |||||
HAVE_MF_DEPS = $(shell pkg-config --exists smf && echo true) | |||||
HAVE_PM_DEPS = $(shell pkg-config --exists libprojectM && echo true) | |||||
HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml zlib && echo true) | HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml zlib && echo true) | ||||
HAVE_ZYN_UI_DEPS = $(shell pkg-config --exists ntk_images ntk && echo true) | HAVE_ZYN_UI_DEPS = $(shell pkg-config --exists ntk_images ntk && echo true) | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Set base defines | # Set base defines | ||||
ifeq ($(HAVE_FFMPEG),true) | |||||
BASE_FLAGS += -DHAVE_FFMPEG | |||||
endif | |||||
ifeq ($(HAVE_JUCE_UI),true) | ifeq ($(HAVE_JUCE_UI),true) | ||||
BASE_FLAGS += -DHAVE_JUCE_UI | BASE_FLAGS += -DHAVE_JUCE_UI | ||||
endif | endif | ||||
@@ -256,15 +249,6 @@ endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Set libs stuff (part 2) | # Set libs stuff (part 2) | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
AUDIO_DECODER_FLAGS = $(shell pkg-config --cflags sndfile) | |||||
AUDIO_DECODER_LIBS = $(shell pkg-config --libs sndfile) | |||||
ifeq ($(HAVE_FFMPEG),true) | |||||
AUDIO_DECODER_FLAGS += $(shell pkg-config --cflags libavcodec libavformat libavutil) | |||||
AUDIO_DECODER_LIBS += $(shell pkg-config --libs libavcodec libavformat libavutil) | |||||
endif | |||||
endif | |||||
RTAUDIO_FLAGS = -DHAVE_GETTIMEOFDAY -D__UNIX_JACK__ | RTAUDIO_FLAGS = -DHAVE_GETTIMEOFDAY -D__UNIX_JACK__ | ||||
ifeq ($(DEBUG),true) | ifeq ($(DEBUG),true) | ||||
@@ -334,21 +318,6 @@ endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Set libs stuff (part 3) | # Set libs stuff (part 3) | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
NATIVE_PLUGINS_FLAGS += -DWANT_AUDIOFILE | |||||
NATIVE_PLUGINS_LIBS += $(AUDIO_DECODER_LIBS) | |||||
endif | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
NATIVE_PLUGINS_FLAGS += -DWANT_MIDIFILE | |||||
NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs smf) | |||||
endif | |||||
ifeq ($(HAVE_PM_DEPS),true) | |||||
NATIVE_PLUGINS_FLAGS += -DWANT_PROJECTM | |||||
NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs libprojectM) | |||||
endif | |||||
ifeq ($(HAVE_ZYN_DEPS),true) | ifeq ($(HAVE_ZYN_DEPS),true) | ||||
NATIVE_PLUGINS_FLAGS += -DWANT_ZYNADDSUBFX | NATIVE_PLUGINS_FLAGS += -DWANT_ZYNADDSUBFX | ||||
NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs fftw3 mxml zlib) | NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs fftw3 mxml zlib) | ||||
@@ -593,17 +593,7 @@ const char* carla_get_complete_license_text() | |||||
#ifdef WANT_NATIVE | #ifdef WANT_NATIVE | ||||
// Internal plugins | // Internal plugins | ||||
# ifdef HAVE_OPENGL | |||||
text3 += "<li>DISTRHO Mini-Series plugin code, based on LOSER-dev suite by Michael Gruhn</li>"; | |||||
# endif | |||||
text3 += "<li>NekoFilter plugin code, based on lv2fil by Nedko Arnaudov and Fons Adriaensen</li>"; | text3 += "<li>NekoFilter plugin code, based on lv2fil by Nedko Arnaudov and Fons Adriaensen</li>"; | ||||
//text1 += "<li>SunVox library file support, http://www.warmplace.ru/soft/sunvox/</li>"; // unfinished | |||||
# ifdef WANT_AUDIOFILE | |||||
text3 += "<li>AudioDecoder library for Audio file support, by Robin Gareus</li>"; | |||||
# endif | |||||
# ifdef WANT_MIDIFILE | |||||
text3 += "<li>LibSMF library for MIDI file support, http://libsmf.sourceforge.net/</li>"; | |||||
# endif | |||||
# ifdef WANT_ZYNADDSUBFX | # ifdef WANT_ZYNADDSUBFX | ||||
text3 += "<li>ZynAddSubFX plugin code, http://zynaddsubfx.sf.net/</li>"; | text3 += "<li>ZynAddSubFX plugin code, http://zynaddsubfx.sf.net/</li>"; | ||||
# ifdef WANT_ZYNADDSUBFX_UI | # ifdef WANT_ZYNADDSUBFX_UI | ||||
@@ -660,16 +650,12 @@ const char* carla_get_supported_file_extensions() | |||||
retText += ";*.gig;*.sfz"; | retText += ";*.gig;*.sfz"; | ||||
#endif | #endif | ||||
// Files provided by internal plugins | |||||
#ifdef WANT_AUDIOFILE | |||||
// Audio files, FIXME | |||||
retText += ";*.aiff;*.flac;*.oga;*.ogg;*.w64;*.wav"; | retText += ";*.aiff;*.flac;*.oga;*.ogg;*.w64;*.wav"; | ||||
# ifdef HAVE_FFMPEG | |||||
retText += ";*.3g2;*.3gp;*.aac;*.ac3;*.amr;*.ape;*.mp2;*.mp3;*.mpc;*.wma"; | retText += ";*.3g2;*.3gp;*.aac;*.ac3;*.amr;*.ape;*.mp2;*.mp3;*.mpc;*.wma"; | ||||
# endif | |||||
#endif | |||||
#ifdef WANT_MIDIFILE | |||||
// MIDI files | |||||
retText += ";*.mid;*.midi"; | retText += ";*.mid;*.midi"; | ||||
#endif | |||||
// Plugin presets | // Plugin presets | ||||
#ifdef WANT_ZYNADDSUBFX | #ifdef WANT_ZYNADDSUBFX | ||||
@@ -25,10 +25,6 @@ ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||||
STANDALONE_LIBS += ../modules/lilv.a | STANDALONE_LIBS += ../modules/lilv.a | ||||
endif | endif | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
STANDALONE_LIBS += ../modules/audio_decoder.a | |||||
endif | |||||
ifeq ($(HAVE_JUCE_UI),true) | ifeq ($(HAVE_JUCE_UI),true) | ||||
STANDALONE_LIBS += ../modules/juce_audio_devices.a | STANDALONE_LIBS += ../modules/juce_audio_devices.a | ||||
STANDALONE_LIBS += ../modules/juce_audio_processors.a | STANDALONE_LIBS += ../modules/juce_audio_processors.a | ||||
@@ -913,9 +913,9 @@ bool CarlaEngine::loadFile(const char* const filename) | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// FIXME | |||||
if (extension == "aiff" || extension == "flac" || extension == "oga" || extension == "ogg" || extension == "w64" || extension == "wav") | if (extension == "aiff" || extension == "flac" || extension == "oga" || extension == "ogg" || extension == "w64" || extension == "wav") | ||||
{ | { | ||||
#ifdef WANT_AUDIOFILE | |||||
if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile", 0, nullptr)) | if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile", 0, nullptr)) | ||||
{ | { | ||||
if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | ||||
@@ -923,17 +923,11 @@ bool CarlaEngine::loadFile(const char* const filename) | |||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
#else | |||||
setLastError("This Carla build does not have Audio file support"); | |||||
return false; | |||||
#endif | |||||
} | } | ||||
if (extension == "3g2" || extension == "3gp" || extension == "aac" || extension == "ac3" || extension == "amr" || extension == "ape" || | if (extension == "3g2" || extension == "3gp" || extension == "aac" || extension == "ac3" || extension == "amr" || extension == "ape" || | ||||
extension == "mp2" || extension == "mp3" || extension == "mpc" || extension == "wma") | |||||
extension == "mp2" || extension == "mp3" || extension == "mpc" || extension == "wma") | |||||
{ | { | ||||
#ifdef WANT_AUDIOFILE | |||||
# ifdef HAVE_FFMPEG | |||||
if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile", 0, nullptr)) | if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile", 0, nullptr)) | ||||
{ | { | ||||
if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | ||||
@@ -941,21 +935,12 @@ bool CarlaEngine::loadFile(const char* const filename) | |||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
# else | |||||
setLastError("This Carla build has Audio file support, but not libav/ffmpeg"); | |||||
return false; | |||||
# endif | |||||
#else | |||||
setLastError("This Carla build does not have Audio file support"); | |||||
return false; | |||||
#endif | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
if (extension == "mid" || extension == "midi") | if (extension == "mid" || extension == "midi") | ||||
{ | { | ||||
#ifdef WANT_MIDIFILE | |||||
if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "midifile", 0, nullptr)) | if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "midifile", 0, nullptr)) | ||||
{ | { | ||||
if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | ||||
@@ -963,10 +948,6 @@ bool CarlaEngine::loadFile(const char* const filename) | |||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
#else | |||||
setLastError("This Carla build does not have MIDI file support"); | |||||
return false; | |||||
#endif | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -2267,21 +2267,6 @@ public: | |||||
pData->iconName = carla_strdup("file"); | pData->iconName = carla_strdup("file"); | ||||
else if (std::strcmp(fDescriptor->label, "midifile") == 0) | else if (std::strcmp(fDescriptor->label, "midifile") == 0) | ||||
pData->iconName = carla_strdup("file"); | pData->iconName = carla_strdup("file"); | ||||
else if (std::strcmp(fDescriptor->label, "sunvoxfile") == 0) | |||||
pData->iconName = carla_strdup("file"); | |||||
else if (std::strcmp(fDescriptor->label, "3BandEQ") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
else if (std::strcmp(fDescriptor->label, "3BandSplitter") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
else if (std::strcmp(fDescriptor->label, "Nekobi") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
else if (std::strcmp(fDescriptor->label, "Notes") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
else if (std::strcmp(fDescriptor->label, "PingPongPan") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
else if (std::strcmp(fDescriptor->label, "StereoEnhancer") == 0) | |||||
pData->iconName = carla_strdup("distrho"); | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// get info | // get info | ||||
@@ -85,14 +85,6 @@ NATIVE_BUILD_FLAGS += $(LINUXSAMPLER_FLAGS) | |||||
NATIVE_LINK_FLAGS += $(LINUXSAMPLER_LIBS) | NATIVE_LINK_FLAGS += $(LINUXSAMPLER_LIBS) | ||||
endif | endif | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
NATIVE_BUILD_FLAGS += -DWANT_AUDIOFILE | |||||
endif | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
NATIVE_BUILD_FLAGS += -DWANT_MIDIFILE | |||||
endif | |||||
ifeq ($(HAVE_ZYN_DEPS),true) | ifeq ($(HAVE_ZYN_DEPS),true) | ||||
NATIVE_BUILD_FLAGS += -DWANT_ZYNADDSUBFX | NATIVE_BUILD_FLAGS += -DWANT_ZYNADDSUBFX | ||||
ifeq ($(HAVE_ZYN_UI_DEPS),true) | ifeq ($(HAVE_ZYN_UI_DEPS),true) | ||||
@@ -502,11 +494,6 @@ LIBS_NATIVE += \ | |||||
../modules/juce_gui_extra.a | ../modules/juce_gui_extra.a | ||||
endif | endif | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
LIBS_NATIVE += \ | |||||
../modules/audio_decoder.a | |||||
endif | |||||
ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ||||
LIBS_NATIVE += \ | LIBS_NATIVE += \ | ||||
../modules/lilv.a | ../modules/lilv.a | ||||
@@ -1,286 +0,0 @@ | |||||
#ifndef __SUNVOX_H__ | |||||
#define __SUNVOX_H__ | |||||
#define NOTECMD_NOTE_OFF 128 | |||||
#define NOTECMD_ALL_NOTES_OFF 129 /* notes of all synths off */ | |||||
#define NOTECMD_CLEAN_SYNTHS 130 /* stop and clean all synths */ | |||||
#define NOTECMD_STOP 131 | |||||
#define NOTECMD_PLAY 132 | |||||
//sv_send_event() parameters: | |||||
// slot; | |||||
// channel_num: from 0 to 7; | |||||
// note: 0 - nothing; 1..127 - note num; 128 - note off; 129, 130... - see NOTECMD_xxx defines; | |||||
// vel: velocity 1..129; 0 - default; | |||||
// module: 0 - nothing; 1..255 - module number; | |||||
// ctl: CCXX. CC - number of controller. XX - std effect; | |||||
// ctl_val: value of controller. | |||||
typedef struct | |||||
{ | |||||
unsigned char note; //0 - nothing; 1..127 - note num; 128 - note off; 129, 130... - see NOTECMD_xxx defines | |||||
unsigned char vel; //Velocity 1..129; 0 - default | |||||
unsigned char module; //0 - nothing; 1..255 - module number | |||||
unsigned char nothing; | |||||
unsigned short ctl; //CCXX. CC - number of controller. XX - std effect | |||||
unsigned short ctl_val; //Value of controller | |||||
} sunvox_note; | |||||
#define SV_INIT_FLAG_NO_DEBUG_OUTPUT ( 1 << 0 ) | |||||
#define SV_INIT_FLAG_USER_AUDIO_CALLBACK ( 1 << 1 ) /* Interaction with sound card is on the user side */ | |||||
#define SV_INIT_FLAG_AUDIO_INT16 ( 1 << 2 ) | |||||
#define SV_INIT_FLAG_AUDIO_FLOAT32 ( 1 << 3 ) | |||||
#define SV_INIT_FLAG_ONE_THREAD ( 1 << 4 ) /* Audio callback and song modification functions are in single thread */ | |||||
#define SV_MODULE_FLAG_EXISTS 1 | |||||
#define SV_MODULE_FLAG_EFFECT 2 | |||||
#define SV_MODULE_INPUTS_OFF 16 | |||||
#define SV_MODULE_INPUTS_MASK ( 255 << SV_MODULE_INPUTS_OFF ) | |||||
#define SV_MODULE_OUTPUTS_OFF ( 16 + 8 ) | |||||
#define SV_MODULE_OUTPUTS_MASK ( 255 << SV_MODULE_OUTPUTS_OFF ) | |||||
#define SV_STYPE_INT16 0 | |||||
#define SV_STYPE_INT32 1 | |||||
#define SV_STYPE_FLOAT32 2 | |||||
#define SV_STYPE_FLOAT64 3 | |||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) | |||||
#define WIN | |||||
#define LIBNAME "sunvox.dll" | |||||
#endif | |||||
#if defined(__APPLE__) | |||||
#define OSX | |||||
#define LIBNAME "sunvox.dylib" | |||||
#endif | |||||
#if defined(__linux__) || defined(linux) | |||||
#define LINUX | |||||
#define LIBNAME "sunvox.so" | |||||
#endif | |||||
#if defined(OSX) || defined(LINUX) | |||||
#define UNIX | |||||
#endif | |||||
#ifdef WIN | |||||
#define SUNVOX_FN_ATTR __attribute__((stdcall)) | |||||
#endif | |||||
#ifndef SUNVOX_FN_ATTR | |||||
#define SUNVOX_FN_ATTR /**/ | |||||
#endif | |||||
//sv_audio_callback() - get the next piece of SunVox audio. | |||||
//buf - destination buffer of type signed short (if SV_INIT_FLAG_AUDIO_INT16 used in sv_init()) | |||||
// or float (if SV_INIT_FLAG_AUDIO_FLOAT32 used in sv_init()); | |||||
// stereo data will be interleaved in this buffer: LRLR... ; where the LR is the one frame; | |||||
//frames - number of frames in destination buffer; | |||||
//latency - audio latency (in frames); | |||||
//out_time - output time (in ticks). | |||||
typedef int (*tsv_audio_callback)( void* buf, int frames, int latency, unsigned int out_time ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_open_slot)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_close_slot)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_lock_slot)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_unlock_slot)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_init)( const char* dev, int freq, int channels, int flags ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_deinit)( void ) SUNVOX_FN_ATTR; | |||||
//sv_get_sample_type() - get internal sample type of the SunVox engine. Return value: one of the SV_STYPE_xxx defines. | |||||
//Use it to get the scope buffer type from get_module_scope() function. | |||||
typedef int (*tsv_get_sample_type)( void ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_load)( int slot, const char* name ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_load_from_memory)( int slot, void* data, unsigned int data_size ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_play)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_play_from_beginning)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_stop)( int slot ) SUNVOX_FN_ATTR; | |||||
//autostop values: 0 - disable autostop; 1 - enable autostop. | |||||
//When disabled, song is playing infinitely in the loop. | |||||
typedef int (*tsv_set_autostop)( int slot, int autostop ) SUNVOX_FN_ATTR; | |||||
//sv_end_of_song() return values: 0 - song is playing now; 1 - stopped. | |||||
typedef int (*tsv_end_of_song)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_rewind)( int slot, int t ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_volume)( int slot, int vol ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_send_event)( int slot, int channel_num, int note, int vel, int module, int ctl, int ctl_val ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_current_line)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_current_signal_level)( int slot, int channel ) SUNVOX_FN_ATTR; //From 0 to 255 | |||||
typedef const char* (*tsv_get_song_name)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_song_bpm)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_song_tpl)( int slot ) SUNVOX_FN_ATTR; | |||||
//Frame is one discrete of the sound. Sampling frequency 44100 Hz means, that you hear 44100 frames per second. | |||||
typedef unsigned int (*tsv_get_song_length_frames)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef unsigned int (*tsv_get_song_length_lines)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_number_of_modules)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_module_flags)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef int* (*tsv_get_module_inputs)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef int* (*tsv_get_module_outputs)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef const char* (*tsv_get_module_name)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef unsigned int (*tsv_get_module_xy)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_module_color)( int slot, int mod_num ) SUNVOX_FN_ATTR; | |||||
typedef void* (*tsv_get_module_scope)( int slot, int mod_num, int channel, int* offset, int* buffer_size ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_number_of_patterns)( int slot ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_pattern_x)( int slot, int pat_num ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_pattern_y)( int slot, int pat_num ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_pattern_tracks)( int slot, int pat_num ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_get_pattern_lines)( int slot, int pat_num ) SUNVOX_FN_ATTR; | |||||
typedef sunvox_note* (*tsv_get_pattern_data)( int slot, int pat_num ) SUNVOX_FN_ATTR; | |||||
typedef int (*tsv_pattern_mute)( int slot, int pat_num, int mute ) SUNVOX_FN_ATTR; //Use it with sv_lock_slot() and sv_unlock_slot() | |||||
//SunVox engine uses its own time space, measured in ticks. | |||||
//Use sv_get_ticks() to get current tick counter (from 0 to 0xFFFFFFFF). | |||||
//Use sv_get_ticks_per_second() to get the number of SunVox ticks per second. | |||||
typedef unsigned int (*tsv_get_ticks)( void ) SUNVOX_FN_ATTR; | |||||
typedef unsigned int (*tsv_get_ticks_per_second)( void ) SUNVOX_FN_ATTR; | |||||
#ifdef SUNVOX_MAIN | |||||
#ifdef WIN | |||||
#define IMPORT( Handle, Type, Function, Store ) \ | |||||
{ \ | |||||
Store = (Type)GetProcAddress( Handle, Function ); \ | |||||
if( Store == 0 ) { fn_not_found = Function; break; } \ | |||||
} | |||||
#define ERROR_MSG( msg ) MessageBox( 0, TEXT("msg"), TEXT("Error"), MB_OK ); | |||||
#endif | |||||
#ifdef UNIX | |||||
#define IMPORT( Handle, Type, Function, Store ) \ | |||||
{ \ | |||||
Store = (Type)dlsym( Handle, Function ); \ | |||||
if( Store == 0 ) { fn_not_found = Function; break; } \ | |||||
} | |||||
#define ERROR_MSG( msg ) printf( "ERROR: %s\n", msg ); | |||||
#endif | |||||
tsv_audio_callback sv_audio_callback = 0; | |||||
tsv_open_slot sv_open_slot = 0; | |||||
tsv_close_slot sv_close_slot = 0; | |||||
tsv_lock_slot sv_lock_slot = 0; | |||||
tsv_unlock_slot sv_unlock_slot = 0; | |||||
tsv_init sv_init = 0; | |||||
tsv_deinit sv_deinit = 0; | |||||
tsv_get_sample_type sv_get_sample_type = 0; | |||||
tsv_load sv_load = 0; | |||||
tsv_load_from_memory sv_load_from_memory = 0; | |||||
tsv_play sv_play = 0; | |||||
tsv_play_from_beginning sv_play_from_beginning = 0; | |||||
tsv_stop sv_stop = 0; | |||||
tsv_set_autostop sv_set_autostop = 0; | |||||
tsv_end_of_song sv_end_of_song = 0; | |||||
tsv_rewind sv_rewind = 0; | |||||
tsv_volume sv_volume = 0; | |||||
tsv_send_event sv_send_event = 0; | |||||
tsv_get_current_line sv_get_current_line = 0; | |||||
tsv_get_current_signal_level sv_get_current_signal_level = 0; | |||||
tsv_get_song_name sv_get_song_name = 0; | |||||
tsv_get_song_bpm sv_get_song_bpm = 0; | |||||
tsv_get_song_tpl sv_get_song_tpl = 0; | |||||
tsv_get_song_length_frames sv_get_song_length_frames = 0; | |||||
tsv_get_song_length_lines sv_get_song_length_lines = 0; | |||||
tsv_get_number_of_modules sv_get_number_of_modules = 0; | |||||
tsv_get_module_flags sv_get_module_flags = 0; | |||||
tsv_get_module_inputs sv_get_module_inputs = 0; | |||||
tsv_get_module_outputs sv_get_module_outputs = 0; | |||||
tsv_get_module_name sv_get_module_name = 0; | |||||
tsv_get_module_xy sv_get_module_xy = 0; | |||||
tsv_get_module_color sv_get_module_color = 0; | |||||
tsv_get_module_scope sv_get_module_scope = 0; | |||||
tsv_get_number_of_patterns sv_get_number_of_patterns = 0; | |||||
tsv_get_pattern_x sv_get_pattern_x = 0; | |||||
tsv_get_pattern_y sv_get_pattern_y = 0; | |||||
tsv_get_pattern_tracks sv_get_pattern_tracks = 0; | |||||
tsv_get_pattern_lines sv_get_pattern_lines = 0; | |||||
tsv_get_pattern_data sv_get_pattern_data = 0; | |||||
tsv_pattern_mute sv_pattern_mute = 0; | |||||
tsv_get_ticks sv_get_ticks = 0; | |||||
tsv_get_ticks_per_second sv_get_ticks_per_second = 0; | |||||
#ifdef UNIX | |||||
void* g_sv_dll = 0; | |||||
#endif | |||||
#ifdef WIN | |||||
HMODULE g_sv_dll = 0; | |||||
#endif | |||||
int sv_load_dll( void ) | |||||
{ | |||||
#ifdef WIN | |||||
g_sv_dll = LoadLibrary( TEXT(LIBNAME) ); | |||||
if( g_sv_dll == 0 ) | |||||
{ | |||||
ERROR_MSG( "sunvox.dll not found" ); | |||||
return 1; | |||||
} | |||||
#endif | |||||
#ifdef UNIX | |||||
g_sv_dll = dlopen( LIBNAME, RTLD_NOW ); | |||||
if( g_sv_dll == 0 ) | |||||
{ | |||||
printf( "%s\n", dlerror() ); | |||||
return 1; | |||||
} | |||||
#endif | |||||
const char* fn_not_found = 0; | |||||
while( 1 ) | |||||
{ | |||||
IMPORT( g_sv_dll, tsv_audio_callback, "sv_audio_callback", sv_audio_callback ); | |||||
IMPORT( g_sv_dll, tsv_open_slot, "sv_open_slot", sv_open_slot ); | |||||
IMPORT( g_sv_dll, tsv_close_slot, "sv_close_slot", sv_close_slot ); | |||||
IMPORT( g_sv_dll, tsv_lock_slot, "sv_lock_slot", sv_lock_slot ); | |||||
IMPORT( g_sv_dll, tsv_unlock_slot, "sv_unlock_slot", sv_unlock_slot ); | |||||
IMPORT( g_sv_dll, tsv_init, "sv_init", sv_init ); | |||||
IMPORT( g_sv_dll, tsv_deinit, "sv_deinit", sv_deinit ); | |||||
IMPORT( g_sv_dll, tsv_get_sample_type, "sv_get_sample_type", sv_get_sample_type ); | |||||
IMPORT( g_sv_dll, tsv_load, "sv_load", sv_load ); | |||||
IMPORT( g_sv_dll, tsv_load_from_memory, "sv_load_from_memory", sv_load_from_memory ); | |||||
IMPORT( g_sv_dll, tsv_play, "sv_play", sv_play ); | |||||
IMPORT( g_sv_dll, tsv_play_from_beginning, "sv_play_from_beginning", sv_play_from_beginning ); | |||||
IMPORT( g_sv_dll, tsv_stop, "sv_stop", sv_stop ); | |||||
IMPORT( g_sv_dll, tsv_set_autostop, "sv_set_autostop", sv_set_autostop ); | |||||
IMPORT( g_sv_dll, tsv_end_of_song, "sv_end_of_song", sv_end_of_song ); | |||||
IMPORT( g_sv_dll, tsv_rewind, "sv_rewind", sv_rewind ); | |||||
IMPORT( g_sv_dll, tsv_volume, "sv_volume", sv_volume ); | |||||
IMPORT( g_sv_dll, tsv_send_event, "sv_send_event", sv_send_event ); | |||||
IMPORT( g_sv_dll, tsv_get_current_line, "sv_get_current_line", sv_get_current_line ); | |||||
IMPORT( g_sv_dll, tsv_get_current_signal_level, "sv_get_current_signal_level", sv_get_current_signal_level ); | |||||
IMPORT( g_sv_dll, tsv_get_song_name, "sv_get_song_name", sv_get_song_name ); | |||||
IMPORT( g_sv_dll, tsv_get_song_bpm, "sv_get_song_bpm", sv_get_song_bpm ); | |||||
IMPORT( g_sv_dll, tsv_get_song_tpl, "sv_get_song_tpl", sv_get_song_tpl ); | |||||
IMPORT( g_sv_dll, tsv_get_song_length_frames, "sv_get_song_length_frames", sv_get_song_length_frames ); | |||||
IMPORT( g_sv_dll, tsv_get_song_length_lines, "sv_get_song_length_lines", sv_get_song_length_lines ); | |||||
IMPORT( g_sv_dll, tsv_get_number_of_modules, "sv_get_number_of_modules", sv_get_number_of_modules ); | |||||
IMPORT( g_sv_dll, tsv_get_module_flags, "sv_get_module_flags", sv_get_module_flags ); | |||||
IMPORT( g_sv_dll, tsv_get_module_inputs, "sv_get_module_inputs", sv_get_module_inputs ); | |||||
IMPORT( g_sv_dll, tsv_get_module_outputs, "sv_get_module_outputs", sv_get_module_outputs ); | |||||
IMPORT( g_sv_dll, tsv_get_module_name, "sv_get_module_name", sv_get_module_name ); | |||||
IMPORT( g_sv_dll, tsv_get_module_xy, "sv_get_module_xy", sv_get_module_xy ); | |||||
IMPORT( g_sv_dll, tsv_get_module_color, "sv_get_module_color", sv_get_module_color ); | |||||
IMPORT( g_sv_dll, tsv_get_module_scope, "sv_get_module_scope", sv_get_module_scope ); | |||||
IMPORT( g_sv_dll, tsv_get_number_of_patterns, "sv_get_number_of_patterns", sv_get_number_of_patterns ); | |||||
IMPORT( g_sv_dll, tsv_get_pattern_x, "sv_get_pattern_x", sv_get_pattern_x ); | |||||
IMPORT( g_sv_dll, tsv_get_pattern_y, "sv_get_pattern_y", sv_get_pattern_y ); | |||||
IMPORT( g_sv_dll, tsv_get_pattern_tracks, "sv_get_pattern_tracks", sv_get_pattern_tracks ); | |||||
IMPORT( g_sv_dll, tsv_get_pattern_lines, "sv_get_pattern_lines", sv_get_pattern_lines ); | |||||
IMPORT( g_sv_dll, tsv_get_pattern_data, "sv_get_pattern_data", sv_get_pattern_data ); | |||||
IMPORT( g_sv_dll, tsv_pattern_mute, "sv_pattern_mute", sv_pattern_mute ); | |||||
IMPORT( g_sv_dll, tsv_get_ticks, "sv_get_ticks", sv_get_ticks ); | |||||
IMPORT( g_sv_dll, tsv_get_ticks_per_second, "sv_get_ticks_per_second", sv_get_ticks_per_second ); | |||||
break; | |||||
} | |||||
if( fn_not_found ) | |||||
{ | |||||
char ts[ 256 ]; | |||||
sprintf( ts, "sunvox lib: %s() not found", fn_not_found ); | |||||
ERROR_MSG( ts ); | |||||
return -1; | |||||
} | |||||
return 0; | |||||
} | |||||
int sv_unload_dll( void ) | |||||
{ | |||||
#ifdef UNIX | |||||
if( g_sv_dll ) dlclose( g_sv_dll ); | |||||
#endif | |||||
return 0; | |||||
} | |||||
#endif | |||||
#endif |
@@ -60,8 +60,6 @@ jackbridge-wine64: | |||||
clean: | clean: | ||||
rm -f *.a *.def *.dll *.dylib *.so | rm -f *.a *.def *.dll *.dylib *.so | ||||
$(MAKE) clean -C audio_decoder | |||||
$(MAKE) clean -C dgl | |||||
$(MAKE) clean -C jackbridge | $(MAKE) clean -C jackbridge | ||||
$(MAKE) clean -C juce_audio_basics | $(MAKE) clean -C juce_audio_basics | ||||
$(MAKE) clean -C juce_audio_devices | $(MAKE) clean -C juce_audio_devices | ||||
@@ -78,13 +76,12 @@ clean: | |||||
$(MAKE) clean -C rtaudio | $(MAKE) clean -C rtaudio | ||||
$(MAKE) clean -C rtmempool | $(MAKE) clean -C rtmempool | ||||
$(MAKE) clean -C rtmidi | $(MAKE) clean -C rtmidi | ||||
$(MAKE) clean -C stk | |||||
$(MAKE) clean -C theme | $(MAKE) clean -C theme | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
.PHONY: \ | .PHONY: \ | ||||
audio_decoder dgl jackbridge lilv native-plugins rtaudio rtmempool rtmidi stk theme \ | |||||
jackbridge lilv native-plugins rtaudio rtmempool rtmidi theme \ | |||||
juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra | juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- |
@@ -1,53 +0,0 @@ | |||||
#!/usr/bin/make -f | |||||
# Makefile for audio_decoder # | |||||
# -------------------------- # | |||||
# Created by falkTX | |||||
# | |||||
include ../../Makefile.mk | |||||
# -------------------------------------------------------------- | |||||
BUILD_C_FLAGS += $(AUDIO_DECODER_FLAGS) -I. -I.. -w | |||||
# -------------------------------------------------------------- | |||||
OBJS = \ | |||||
ad_ffmpeg.c.o \ | |||||
ad_plugin.c.o \ | |||||
ad_soundfile.c.o | |||||
TARGETS = \ | |||||
../audio_decoder.a | |||||
# -------------------------------------------------------------- | |||||
all: $(TARGETS) | |||||
# -------------------------------------------------------------- | |||||
clean: | |||||
$(RM) $(OBJS) | |||||
$(RM) $(TARGETS) | |||||
debug: | |||||
$(MAKE) DEBUG=true | |||||
# -------------------------------------------------------------- | |||||
../audio_decoder.a: $(OBJS) | |||||
$(RM) $@ | |||||
$(AR) crs $@ $^ | |||||
# -------------------------------------------------------------- | |||||
ad_ffmpeg.c.o: ad_ffmpeg.c ad_plugin.h ffcompat.h ad.h | |||||
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||||
ad_plugin.c.o: ad_plugin.c ad_plugin.h ad.h | |||||
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||||
ad_soundfile.c.o: ad_soundfile.c ad_plugin.h ad.h | |||||
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||||
# -------------------------------------------------------------- |
@@ -1,127 +0,0 @@ | |||||
/** | |||||
@brief audio-decoder - wrapper around libsndfile and libav* | |||||
@file ad.h | |||||
@author Robin Gareus <robin@gareus.org> | |||||
Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org> | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser Public License as published by | |||||
the Free Software Foundation; either version 2.1, or (at your option) | |||||
any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public | |||||
License along with this library; if not, write to the Free Software | |||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||||
*/ | |||||
#ifndef __AD_H__ | |||||
#define __AD_H__ | |||||
#include <unistd.h> | |||||
#include <stdint.h> | |||||
struct adinfo { | |||||
unsigned int sample_rate; | |||||
unsigned int channels; | |||||
int64_t length; //milliseconds | |||||
int64_t frames; //total number of frames (eg a frame for 16bit stereo is 4 bytes). | |||||
int bit_rate; | |||||
int bit_depth; | |||||
char * meta_data; | |||||
}; | |||||
/* global init function - register codecs */ | |||||
void ad_init(); | |||||
/* --- public API --- */ | |||||
/** open an audio file | |||||
* @param fn file-name | |||||
* @param nfo pointer to a adinfo struct which will hold information about the file. | |||||
* @return NULL on error, a pointer to an opaque soundfile-decoder object on success. | |||||
*/ | |||||
void * ad_open (const char *fn, struct adinfo *nfo); | |||||
/** close an audio file and release decoder structures | |||||
* @param sf decoder handle | |||||
* @return 0 on succees, -1 if sf was invalid or not open (return value can usually be ignored) | |||||
*/ | |||||
int ad_close (void *sf); | |||||
/** seel to a given position in the file | |||||
* @param sf decoder handle | |||||
* @param pos frame position to seek to in frames (1 frame = number-of-channel samples) from the start of the file. | |||||
* @return the current position in frames (multi-channel samples) from the start of the file. On error this function returns -1. | |||||
*/ | |||||
int64_t ad_seek (void *sf, int64_t pos); | |||||
/** decode audio data chunk to raw interleaved channel floating point data | |||||
* | |||||
* @param sf decoder handle | |||||
* @param out place to store data -- must be large enough to hold (sizeof(float) * len) bytes. | |||||
* @param len number of samples (!) to read (should be a multiple of nfo->channels). | |||||
* @return the number of read samples. | |||||
*/ | |||||
ssize_t ad_read (void *sf, float* out, size_t len); | |||||
/** re-read the file information and meta-data. | |||||
* | |||||
* this is not neccesary in general \ref ad_open includes an inplicit call | |||||
* but meta-data may change in live-stream in which case en explicit call to | |||||
* ad_into is needed to update the inforation | |||||
* | |||||
* @param fn file-name | |||||
* @param nfo pointer to a adinfo struct which will hold information about the file. | |||||
* @return 0 on succees, -1 if sf was invalid or not open | |||||
*/ | |||||
int ad_info (void *sf, struct adinfo *nfo); | |||||
/** zero initialize the information struct. * (does not free nfo->meta_data) | |||||
* @param nfo pointer to a adinfo struct | |||||
*/ | |||||
void ad_clear_nfo (struct adinfo *nfo); | |||||
/** free possibly allocated meta-data text | |||||
* @param nfo pointer to a adinfo struct | |||||
*/ | |||||
void ad_free_nfo (struct adinfo *nfo); | |||||
/* --- helper functions --- */ | |||||
/** read file info | |||||
* combines ad_open() and ad_close() | |||||
*/ | |||||
int ad_finfo (const char *, struct adinfo *); | |||||
/** | |||||
* wrapper around \ref ad_read, downmixes all channels to mono | |||||
*/ | |||||
ssize_t ad_read_mono_dbl (void *, struct adinfo *, double*, size_t); | |||||
/** | |||||
* calls dbg() to print file info to stderr. | |||||
* | |||||
* @param dbglvl | |||||
* @param nfo | |||||
*/ | |||||
void ad_dump_nfo (int dbglvl, struct adinfo *nfo); | |||||
/** set audio-decoder debug level -- all info is printed to stderr. | |||||
* | |||||
* @param lvl debug-level threshold | |||||
* -1: absolutley silent | |||||
* 0: errors only | |||||
* 1: errors + info | |||||
* 2: + debug | |||||
* 3: + low-level-debug info | |||||
*/ | |||||
void ad_set_debuglevel(int lvl); | |||||
#endif |
@@ -1,373 +0,0 @@ | |||||
/** | |||||
Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org> | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser Public License as published by | |||||
the Free Software Foundation; either version 2.1, or (at your option) | |||||
any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public | |||||
License along with this library; if not, write to the Free Software | |||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include "ad_plugin.h" | |||||
#ifdef HAVE_FFMPEG | |||||
#include "ffcompat.h" | |||||
#ifndef MIN | |||||
#define MIN(a,b) ( ( (a) < (b) )? (a) : (b) ) | |||||
#endif | |||||
typedef struct { | |||||
AVFormatContext* formatContext; | |||||
AVCodecContext* codecContext; | |||||
AVCodec* codec; | |||||
AVPacket packet; | |||||
int audioStream; | |||||
int pkt_len; | |||||
uint8_t* pkt_ptr; | |||||
int16_t m_tmpBuffer[AVCODEC_MAX_AUDIO_FRAME_SIZE]; | |||||
int16_t* m_tmpBufferStart; | |||||
unsigned long m_tmpBufferLen; | |||||
int64_t decoder_clock; | |||||
int64_t output_clock; | |||||
int64_t seek_frame; | |||||
unsigned int samplerate; | |||||
unsigned int channels; | |||||
int64_t length; | |||||
} ffmpeg_audio_decoder; | |||||
static int ad_info_ffmpeg(void *sf, struct adinfo *nfo) { | |||||
ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
if (nfo) { | |||||
nfo->sample_rate = priv->samplerate; | |||||
nfo->channels = priv->channels; | |||||
nfo->frames = priv->length; | |||||
if (nfo->sample_rate==0) return -1; | |||||
nfo->length = (nfo->frames * 1000) / nfo->sample_rate; | |||||
nfo->bit_rate = priv->formatContext->bit_rate; | |||||
nfo->bit_depth = 0; | |||||
nfo->meta_data = NULL; | |||||
#ifdef WITH_GTK // XXX replace g_* functions with POSIX equiv | |||||
AVDictionaryEntry *tag = NULL; | |||||
// Tags in container | |||||
while ((tag = av_dict_get(priv->formatContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { | |||||
dbg(2, "FTAG: %s=%s", tag->key, tag->value); | |||||
char * tmp = g_strdup_printf("%s%s<i>%s</i>:%s", nfo->meta_data?nfo->meta_data:"",nfo->meta_data?"\n":"", tag->key, tag->value); | |||||
if (nfo->meta_data) g_free(nfo->meta_data); | |||||
nfo->meta_data = tmp; | |||||
} | |||||
// Tags in stream | |||||
tag=NULL; | |||||
AVStream *stream = priv->formatContext->streams[priv->audioStream]; | |||||
while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { | |||||
dbg(2, "STAG: %s=%s", tag->key, tag->value); | |||||
char * tmp = g_strdup_printf("%s%s<i>%s</i>:%s", nfo->meta_data?nfo->meta_data:"",nfo->meta_data?"\n":"", tag->key, tag->value); | |||||
if (nfo->meta_data) g_free(nfo->meta_data); | |||||
nfo->meta_data = tmp; | |||||
} | |||||
#endif | |||||
} | |||||
return 0; | |||||
} | |||||
static void *ad_open_ffmpeg(const char *fn, struct adinfo *nfo) { | |||||
ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) calloc(1, sizeof(ffmpeg_audio_decoder)); | |||||
priv->m_tmpBufferStart=NULL; | |||||
priv->m_tmpBufferLen=0; | |||||
priv->decoder_clock=priv->output_clock=priv->seek_frame=0; | |||||
priv->packet.size=0; priv->packet.data=NULL; | |||||
if (avformat_open_input(&priv->formatContext, fn, NULL, NULL) <0) { | |||||
dbg(0, "ffmpeg is unable to open file '%s'.", fn); | |||||
free(priv); return(NULL); | |||||
} | |||||
if (avformat_find_stream_info(priv->formatContext, NULL) < 0) { | |||||
avformat_close_input(&priv->formatContext); | |||||
dbg(0, "av_find_stream_info failed" ); | |||||
free(priv); return(NULL); | |||||
} | |||||
priv->audioStream = -1; | |||||
unsigned int i; | |||||
for (i=0; i<priv->formatContext->nb_streams; i++) { | |||||
if (priv->formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { | |||||
priv->audioStream = i; | |||||
break; | |||||
} | |||||
} | |||||
if (priv->audioStream == -1) { | |||||
dbg(0, "No Audio Stream found in file"); | |||||
avformat_close_input(&priv->formatContext); | |||||
free(priv); return(NULL); | |||||
} | |||||
priv->codecContext = priv->formatContext->streams[priv->audioStream]->codec; | |||||
priv->codec = avcodec_find_decoder(priv->codecContext->codec_id); | |||||
if (priv->codec == NULL) { | |||||
avformat_close_input(&priv->formatContext); | |||||
dbg(0, "Codec not supported by ffmpeg"); | |||||
free(priv); return(NULL); | |||||
} | |||||
if (avcodec_open2(priv->codecContext, priv->codec, NULL) < 0) { | |||||
dbg(0, "avcodec_open failed" ); | |||||
free(priv); return(NULL); | |||||
} | |||||
dbg(2, "ffmpeg - audio tics: %i/%i [sec]",priv->formatContext->streams[priv->audioStream]->time_base.num,priv->formatContext->streams[priv->audioStream]->time_base.den); | |||||
int64_t len = priv->formatContext->duration - priv->formatContext->start_time; | |||||
priv->formatContext->flags|=AVFMT_FLAG_GENPTS; | |||||
priv->formatContext->flags|=AVFMT_FLAG_IGNIDX; | |||||
priv->samplerate = priv->codecContext->sample_rate; | |||||
priv->channels = priv->codecContext->channels ; | |||||
priv->length = (int64_t)( len * priv->samplerate / AV_TIME_BASE ); | |||||
if (ad_info_ffmpeg((void*)priv, nfo)) { | |||||
dbg(0, "invalid file info (sample-rate==0)"); | |||||
free(priv); return(NULL); | |||||
} | |||||
dbg(1, "ffmpeg - %s", fn); | |||||
if (nfo) | |||||
dbg(1, "ffmpeg - sr:%i c:%i d:%"PRIi64" f:%"PRIi64, nfo->sample_rate, nfo->channels, nfo->length, nfo->frames); | |||||
return (void*) priv; | |||||
} | |||||
static int ad_close_ffmpeg(void *sf) { | |||||
ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
avcodec_close(priv->codecContext); | |||||
avformat_close_input(&priv->formatContext); | |||||
free(priv); | |||||
return 0; | |||||
} | |||||
static void int16_to_float(int16_t *in, float *out, int num_channels, int num_samples, int out_offset) { | |||||
int i,ii; | |||||
for (i=0;i<num_samples;i++) { | |||||
for (ii=0;ii<num_channels;ii++) { | |||||
out[(i+out_offset)*num_channels+ii]= (float) in[i*num_channels+ii]/ 32768.0; | |||||
} | |||||
} | |||||
} | |||||
static ssize_t ad_read_ffmpeg(void *sf, float* d, size_t len) { | |||||
ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
size_t frames = len / priv->channels; | |||||
size_t written = 0; | |||||
ssize_t ret = 0; | |||||
while (ret >= 0 && written < frames) { | |||||
dbg(3,"loop: %i/%i (bl:%lu)",written, frames, priv->m_tmpBufferLen ); | |||||
if (priv->seek_frame == 0 && priv->m_tmpBufferLen > 0 ) { | |||||
int s = MIN(priv->m_tmpBufferLen / priv->channels, frames - written ); | |||||
int16_to_float(priv->m_tmpBufferStart, d, priv->channels, s , written); | |||||
written += s; | |||||
priv->output_clock+=s; | |||||
s = s * priv->channels; | |||||
priv->m_tmpBufferStart += s; | |||||
priv->m_tmpBufferLen -= s; | |||||
ret = 0; | |||||
} else { | |||||
priv->m_tmpBufferStart = priv->m_tmpBuffer; | |||||
priv->m_tmpBufferLen = 0; | |||||
if (!priv->pkt_ptr || priv->pkt_len <1 ) { | |||||
if (priv->packet.data) av_free_packet(&priv->packet); | |||||
ret = av_read_frame(priv->formatContext, &priv->packet); | |||||
if (ret<0) { dbg(1, "reached end of file."); break; } | |||||
priv->pkt_len = priv->packet.size; | |||||
priv->pkt_ptr = priv->packet.data; | |||||
} | |||||
if (priv->packet.stream_index != priv->audioStream) { | |||||
priv->pkt_ptr = NULL; | |||||
continue; | |||||
} | |||||
/* decode all chunks in packet */ | |||||
int data_size= AVCODEC_MAX_AUDIO_FRAME_SIZE; | |||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 0, 0) | |||||
/* This works but is not optimal (channels may not be planar/interleaved) */ | |||||
AVFrame avf; // TODO statically allocate as poart of priv->.. | |||||
memset(&avf, 0, sizeof(AVFrame)); // not sure if that is needed | |||||
int got_frame = 0; | |||||
ret = avcodec_decode_audio4(priv->codecContext, &avf, &got_frame, &priv->packet); | |||||
data_size = avf.linesize[0]; | |||||
memcpy(priv->m_tmpBuffer, avf.data[0], avf.linesize[0] * sizeof(uint8_t)); | |||||
#elif LIBAVUTIL_VERSION_INT > AV_VERSION_INT(49, 15, 0) && LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 20, 1) // ?? | |||||
// this was deprecated in LIBAVCODEC_VERSION_MAJOR 53 | |||||
ret = avcodec_decode_audio3(priv->codecContext, | |||||
priv->m_tmpBuffer, &data_size, &priv->packet); | |||||
#else | |||||
int len = priv->packet.size; | |||||
uint8_t *ptr = priv->packet.data; | |||||
ret = avcodec_decode_audio2(priv->codecContext, | |||||
priv->m_tmpBuffer, &data_size, ptr, len); | |||||
#endif | |||||
if (ret < 0 || ret > priv->pkt_len) { | |||||
#if 0 | |||||
dbg(0, "audio decode error"); | |||||
return -1; | |||||
#endif | |||||
priv->pkt_len=0; | |||||
ret=0; | |||||
continue; | |||||
} | |||||
priv->pkt_len -= ret; priv->pkt_ptr += ret; | |||||
/* sample exact alignment */ | |||||
if (priv->packet.pts != AV_NOPTS_VALUE) { | |||||
priv->decoder_clock = priv->samplerate * av_q2d(priv->formatContext->streams[priv->audioStream]->time_base) * priv->packet.pts; | |||||
} else { | |||||
dbg(0, "!!! NO PTS timestamp in file"); | |||||
priv->decoder_clock += (data_size>>1) / priv->channels; | |||||
} | |||||
if (data_size>0) { | |||||
priv->m_tmpBufferLen+= (data_size>>1); // 2 bytes per sample | |||||
} | |||||
/* align buffer after seek. */ | |||||
if (priv->seek_frame > 0) { | |||||
const int diff = priv->output_clock-priv->decoder_clock; | |||||
if (diff<0) { | |||||
/* seek ended up past the wanted sample */ | |||||
dbg(0, " !!! Audio seek failed."); | |||||
return -1; | |||||
} else if (priv->m_tmpBufferLen < (diff*priv->channels)) { | |||||
/* wanted sample not in current buffer - keep going */ | |||||
dbg(2, " !!! seeked sample was not in decoded buffer. frames-to-go: %li", diff); | |||||
priv->m_tmpBufferLen = 0; | |||||
} else if (diff!=0 && data_size > 0) { | |||||
/* wanted sample is in current buffer but not at the beginnning */ | |||||
dbg(2, " !!! sync buffer to seek. (diff:%i)", diff); | |||||
priv->m_tmpBufferStart+= diff*priv->codecContext->channels; | |||||
priv->m_tmpBufferLen -= diff*priv->codecContext->channels; | |||||
#if 1 | |||||
memmove(priv->m_tmpBuffer, priv->m_tmpBufferStart, priv->m_tmpBufferLen); | |||||
priv->m_tmpBufferStart = priv->m_tmpBuffer; | |||||
#endif | |||||
priv->seek_frame=0; | |||||
priv->decoder_clock += diff; | |||||
} else if (data_size > 0) { | |||||
dbg(2, "Audio exact sync-seek (%"PRIi64" == %"PRIi64")", priv->decoder_clock, priv->seek_frame); | |||||
priv->seek_frame=0; | |||||
} else { | |||||
dbg(0, "Error: no audio data in packet"); | |||||
} | |||||
} | |||||
//dbg(0, "PTS: decoder:%"PRIi64". - want: %"PRIi64, priv->decoder_clock, priv->output_clock); | |||||
//dbg(0, "CLK: frame: %"PRIi64" T:%.3fs",priv->decoder_clock, (float) priv->decoder_clock/priv->samplerate); | |||||
} | |||||
} | |||||
if (written!=frames) { | |||||
dbg(2, "short-read"); | |||||
} | |||||
return written * priv->channels; | |||||
} | |||||
static int64_t ad_seek_ffmpeg(void *sf, int64_t pos) { | |||||
ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf; | |||||
if (!sf) return -1; | |||||
if (pos == priv->output_clock) return pos; | |||||
/* flush internal buffer */ | |||||
priv->m_tmpBufferLen = 0; | |||||
priv->seek_frame = pos; | |||||
priv->output_clock = pos; | |||||
priv->pkt_len = 0; priv->pkt_ptr = NULL; | |||||
priv->decoder_clock = 0; | |||||
#if 0 | |||||
/* TODO seek at least 1 packet before target. | |||||
* for mpeg compressed files, the | |||||
* output may depend on past frames! */ | |||||
if (pos > 8192) pos -= 8192; | |||||
else pos = 0; | |||||
#endif | |||||
const int64_t timestamp = pos / av_q2d(priv->formatContext->streams[priv->audioStream]->time_base) / priv->samplerate; | |||||
dbg(2, "seek frame:%"PRIi64" - idx:%"PRIi64, pos, timestamp); | |||||
av_seek_frame(priv->formatContext, priv->audioStream, timestamp, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); | |||||
avcodec_flush_buffers(priv->codecContext); | |||||
return pos; | |||||
} | |||||
static int ad_eval_ffmpeg(const char *f) { | |||||
char *ext = strrchr(f, '.'); | |||||
if (!ext) return 10; | |||||
// libavformat.. guess_format.. | |||||
return 40; | |||||
} | |||||
#endif | |||||
static const ad_plugin ad_ffmpeg = { | |||||
#ifdef HAVE_FFMPEG | |||||
&ad_eval_ffmpeg, | |||||
&ad_open_ffmpeg, | |||||
&ad_close_ffmpeg, | |||||
&ad_info_ffmpeg, | |||||
&ad_seek_ffmpeg, | |||||
&ad_read_ffmpeg | |||||
#else | |||||
&ad_eval_null, | |||||
&ad_open_null, | |||||
&ad_close_null, | |||||
&ad_info_null, | |||||
&ad_seek_null, | |||||
&ad_read_null | |||||
#endif | |||||
}; | |||||
/* dlopen handler */ | |||||
const ad_plugin * adp_get_ffmpeg() { | |||||
#ifdef HAVE_FFMPEG | |||||
static int ffinit = 0; | |||||
if (!ffinit) { | |||||
ffinit=1; | |||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 5, 0) | |||||
avcodec_init(); | |||||
#endif | |||||
av_register_all(); | |||||
avcodec_register_all(); | |||||
if(ad_debug_level <= 1) | |||||
av_log_set_level(AV_LOG_QUIET); | |||||
else | |||||
av_log_set_level(AV_LOG_VERBOSE); | |||||
} | |||||
#endif | |||||
return &ad_ffmpeg; | |||||
} |
@@ -1,176 +0,0 @@ | |||||
/** | |||||
Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org> | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser Public License as published by | |||||
the Free Software Foundation; either version 2.1, or (at your option) | |||||
any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public | |||||
License along with this library; if not, write to the Free Software | |||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <stdarg.h> | |||||
#include <string.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include "ad_plugin.h" | |||||
int ad_debug_level = 0; | |||||
#define UNUSED(x) (void)(x) | |||||
int ad_eval_null(const char *f) { UNUSED(f); return -1; } | |||||
void * ad_open_null(const char *f, struct adinfo *n) { UNUSED(f); UNUSED(n); return NULL; } | |||||
int ad_close_null(void *x) { UNUSED(x); return -1; } | |||||
int ad_info_null(void *x, struct adinfo *n) { UNUSED(x); UNUSED(n); return -1; } | |||||
int64_t ad_seek_null(void *x, int64_t p) { UNUSED(x); UNUSED(p); return -1; } | |||||
ssize_t ad_read_null(void *x, float*d, size_t s) { UNUSED(x); UNUSED(d); UNUSED(s); return -1;} | |||||
typedef struct { | |||||
ad_plugin const *b; ///< decoder back-end | |||||
void *d; ///< backend data | |||||
} adecoder; | |||||
/* samplecat api */ | |||||
void ad_init() { /* global init */ } | |||||
static ad_plugin const * choose_backend(const char *fn) { | |||||
int max, val; | |||||
ad_plugin const *b=NULL; | |||||
max=0; | |||||
val=adp_get_sndfile()->eval(fn); | |||||
if (val>max) {max=val; b=adp_get_sndfile();} | |||||
val=adp_get_ffmpeg()->eval(fn); | |||||
if (val>max) {max=val; b=adp_get_ffmpeg();} | |||||
return b; | |||||
} | |||||
void *ad_open(const char *fn, struct adinfo *nfo) { | |||||
adecoder *d = (adecoder*) calloc(1, sizeof(adecoder)); | |||||
ad_clear_nfo(nfo); | |||||
d->b = choose_backend(fn); | |||||
if (!d->b) { | |||||
dbg(0, "fatal: no decoder backend available"); | |||||
free(d); | |||||
return NULL; | |||||
} | |||||
d->d = d->b->open(fn, nfo); | |||||
if (!d->d) { | |||||
free(d); | |||||
return NULL; | |||||
} | |||||
return (void*)d; | |||||
} | |||||
int ad_info(void *sf, struct adinfo *nfo) { | |||||
adecoder *d = (adecoder*) sf; | |||||
if (!d) return -1; | |||||
return d->b->info(d->d, nfo); | |||||
} | |||||
int ad_close(void *sf) { | |||||
adecoder *d = (adecoder*) sf; | |||||
if (!d) return -1; | |||||
int rv = d->b->close(d->d); | |||||
free(d); | |||||
return rv; | |||||
} | |||||
int64_t ad_seek(void *sf, int64_t pos) { | |||||
adecoder *d = (adecoder*) sf; | |||||
if (!d) return -1; | |||||
return d->b->seek(d->d, pos); | |||||
} | |||||
ssize_t ad_read(void *sf, float* out, size_t len){ | |||||
adecoder *d = (adecoder*) sf; | |||||
if (!d) return -1; | |||||
return d->b->read(d->d, out, len); | |||||
} | |||||
/* | |||||
* side-effects: allocates buffer | |||||
*/ | |||||
ssize_t ad_read_mono_dbl(void *sf, struct adinfo *nfo, double* d, size_t len){ | |||||
unsigned int c,f; | |||||
unsigned int chn = nfo->channels; | |||||
if (len<1) return 0; | |||||
static float *buf = NULL; | |||||
static size_t bufsiz = 0; | |||||
if (!buf || bufsiz != len*chn) { | |||||
bufsiz=len*chn; | |||||
buf = (float*) realloc((void*)buf, bufsiz * sizeof(float)); | |||||
} | |||||
len = ad_read(sf, buf, bufsiz); | |||||
for (f=0;f< (len/chn);f++) { | |||||
double val=0.0; | |||||
for (c=0;c<chn;c++) { | |||||
val+=buf[f*chn + c]; | |||||
} | |||||
d[f]= val/chn; | |||||
} | |||||
return len/chn; | |||||
} | |||||
int ad_finfo (const char *fn, struct adinfo *nfo) { | |||||
ad_clear_nfo(nfo); | |||||
void * sf = ad_open(fn, nfo); | |||||
return ad_close(sf)?1:0; | |||||
} | |||||
void ad_clear_nfo(struct adinfo *nfo) { | |||||
memset(nfo, 0, sizeof(struct adinfo)); | |||||
} | |||||
void ad_free_nfo(struct adinfo *nfo) { | |||||
if (nfo->meta_data) free(nfo->meta_data); | |||||
} | |||||
void ad_dump_nfo(int dbglvl, struct adinfo *nfo) { | |||||
dbg(dbglvl, "sample_rate: %u", nfo->sample_rate); | |||||
dbg(dbglvl, "channels: %u", nfo->channels); | |||||
dbg(dbglvl, "length: %"PRIi64" ms", nfo->length); | |||||
dbg(dbglvl, "frames: %"PRIi64, nfo->frames); | |||||
dbg(dbglvl, "bit_rate: %d", nfo->bit_rate); | |||||
dbg(dbglvl, "bit_depth: %d", nfo->bit_depth); | |||||
dbg(dbglvl, "channels: %u", nfo->channels); | |||||
dbg(dbglvl, "meta-data: %s", nfo->meta_data?nfo->meta_data:"-"); | |||||
} | |||||
void ad_debug_printf(const char* func, int level, const char* format, ...) { | |||||
va_list args; | |||||
va_start(args, format); | |||||
if (level <= ad_debug_level) { | |||||
fprintf(stderr, "%s(): ", func); | |||||
vfprintf(stderr, format, args); | |||||
fprintf(stderr, "\n"); | |||||
} | |||||
va_end(args); | |||||
} | |||||
void ad_set_debuglevel(int lvl) { | |||||
ad_debug_level = lvl; | |||||
if (ad_debug_level<-1) ad_debug_level=-1; | |||||
if (ad_debug_level>3) ad_debug_level=3; | |||||
} |
@@ -1,64 +0,0 @@ | |||||
/** | |||||
Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org> | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser Public License as published by | |||||
the Free Software Foundation; either version 2.1, or (at your option) | |||||
any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public | |||||
License along with this library; if not, write to the Free Software | |||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||||
*/ | |||||
#ifndef __AD_PLUGIN_H__ | |||||
#define __AD_PLUGIN_H__ | |||||
#include <stdint.h> | |||||
#include "audio_decoder/ad.h" | |||||
#define dbg(A, B, ...) ad_debug_printf(__func__, A, B, ##__VA_ARGS__) | |||||
#ifndef __PRI64_PREFIX | |||||
#if (defined __X86_64__ || defined __LP64__) | |||||
# define __PRI64_PREFIX "l" | |||||
#else | |||||
# define __PRI64_PREFIX "ll" | |||||
#endif | |||||
#endif | |||||
#ifndef PRIu64 | |||||
# define PRIu64 __PRI64_PREFIX "u" | |||||
#endif | |||||
#ifndef PRIi64 | |||||
# define PRIi64 __PRI64_PREFIX "i" | |||||
#endif | |||||
extern int ad_debug_level; | |||||
void ad_debug_printf(const char* func, int level, const char* format, ...); | |||||
typedef struct { | |||||
int (*eval)(const char *); | |||||
void * (*open)(const char *, struct adinfo *); | |||||
int (*close)(void *); | |||||
int (*info)(void *, struct adinfo *); | |||||
int64_t (*seek)(void *, int64_t); | |||||
ssize_t (*read)(void *, float *, size_t); | |||||
} ad_plugin; | |||||
int ad_eval_null(const char *); | |||||
void * ad_open_null(const char *, struct adinfo *); | |||||
int ad_close_null(void *); | |||||
int ad_info_null(void *, struct adinfo *); | |||||
int64_t ad_seek_null(void *, int64_t); | |||||
ssize_t ad_read_null(void *, float*, size_t); | |||||
/* hardcoded backends */ | |||||
const ad_plugin * adp_get_sndfile(); | |||||
const ad_plugin * adp_get_ffmpeg(); | |||||
#endif |
@@ -1,154 +0,0 @@ | |||||
/** | |||||
Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org> | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser Public License as published by | |||||
the Free Software Foundation; either version 2.1, or (at your option) | |||||
any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public | |||||
License along with this library; if not, write to the Free Software | |||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |||||
*/ | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <strings.h> | |||||
#include <unistd.h> | |||||
#include <math.h> | |||||
#include <sndfile.h> | |||||
#include "ad_plugin.h" | |||||
/* internal abstraction */ | |||||
typedef struct { | |||||
SF_INFO sfinfo; | |||||
SNDFILE *sffile; | |||||
} sndfile_audio_decoder; | |||||
static int parse_bit_depth(int format) { | |||||
/* see http://www.mega-nerd.com/libsndfile/api.html */ | |||||
switch (format&0x0f) { | |||||
case SF_FORMAT_PCM_S8: return 8; | |||||
case SF_FORMAT_PCM_16: return 16; /* Signed 16 bit data */ | |||||
case SF_FORMAT_PCM_24: return 24; /* Signed 24 bit data */ | |||||
case SF_FORMAT_PCM_32: return 32; /* Signed 32 bit data */ | |||||
case SF_FORMAT_PCM_U8: return 8; /* Unsigned 8 bit data (WAV and RAW only) */ | |||||
case SF_FORMAT_FLOAT : return 32; /* 32 bit float data */ | |||||
case SF_FORMAT_DOUBLE: return 64; /* 64 bit float data */ | |||||
default: break; | |||||
} | |||||
return 0; | |||||
} | |||||
static int ad_info_sndfile(void *sf, struct adinfo *nfo) { | |||||
sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
if (nfo) { | |||||
nfo->channels = priv->sfinfo.channels; | |||||
nfo->frames = priv->sfinfo.frames; | |||||
nfo->sample_rate = priv->sfinfo.samplerate; | |||||
nfo->length = priv->sfinfo.samplerate ? (priv->sfinfo.frames * 1000) / priv->sfinfo.samplerate : 0; | |||||
nfo->bit_depth = parse_bit_depth(priv->sfinfo.format); | |||||
nfo->bit_rate = nfo->bit_depth * nfo->channels * nfo->sample_rate; | |||||
nfo->meta_data = NULL; | |||||
} | |||||
return 0; | |||||
} | |||||
static void *ad_open_sndfile(const char *fn, struct adinfo *nfo) { | |||||
sndfile_audio_decoder *priv = (sndfile_audio_decoder*) calloc(1, sizeof(sndfile_audio_decoder)); | |||||
priv->sfinfo.format=0; | |||||
if(!(priv->sffile = sf_open(fn, SFM_READ, &priv->sfinfo))){ | |||||
dbg(0, "unable to open file '%s'.", fn); | |||||
puts(sf_strerror(NULL)); | |||||
int e = sf_error(NULL); | |||||
dbg(0, "error=%i", e); | |||||
free(priv); | |||||
return NULL; | |||||
} | |||||
ad_info_sndfile(priv, nfo); | |||||
return (void*) priv; | |||||
} | |||||
static int ad_close_sndfile(void *sf) { | |||||
sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
if(!sf || sf_close(priv->sffile)) { | |||||
dbg(0, "fatal: bad file close.\n"); | |||||
return -1; | |||||
} | |||||
free(priv); | |||||
return 0; | |||||
} | |||||
static int64_t ad_seek_sndfile(void *sf, int64_t pos) { | |||||
sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
return sf_seek(priv->sffile, pos, SEEK_SET); | |||||
} | |||||
static ssize_t ad_read_sndfile(void *sf, float* d, size_t len) { | |||||
sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf; | |||||
if (!priv) return -1; | |||||
return sf_read_float (priv->sffile, d, len); | |||||
} | |||||
static int ad_eval_sndfile(const char *f) { | |||||
char *ext = strrchr(f, '.'); | |||||
if (!ext) return 5; | |||||
/* see http://www.mega-nerd.com/libsndfile/ */ | |||||
if (!strcasecmp(ext, ".wav")) return 100; | |||||
if (!strcasecmp(ext, ".aiff")) return 100; | |||||
if (!strcasecmp(ext, ".aifc")) return 100; | |||||
if (!strcasecmp(ext, ".snd")) return 100; | |||||
if (!strcasecmp(ext, ".au")) return 100; | |||||
if (!strcasecmp(ext, ".paf")) return 100; | |||||
if (!strcasecmp(ext, ".iff")) return 100; | |||||
if (!strcasecmp(ext, ".svx")) return 100; | |||||
if (!strcasecmp(ext, ".sf")) return 100; | |||||
if (!strcasecmp(ext, ".vcc")) return 100; | |||||
if (!strcasecmp(ext, ".w64")) return 100; | |||||
if (!strcasecmp(ext, ".mat4")) return 100; | |||||
if (!strcasecmp(ext, ".mat5")) return 100; | |||||
if (!strcasecmp(ext, ".pvf5")) return 100; | |||||
if (!strcasecmp(ext, ".xi")) return 100; | |||||
if (!strcasecmp(ext, ".htk")) return 100; | |||||
if (!strcasecmp(ext, ".pvf")) return 100; | |||||
if (!strcasecmp(ext, ".sd2")) return 100; | |||||
// libsndfile >= 1.0.18 | |||||
if (!strcasecmp(ext, ".flac")) return 80; | |||||
if (!strcasecmp(ext, ".ogg")) return 80; | |||||
return 0; | |||||
} | |||||
static const ad_plugin ad_sndfile = { | |||||
#if 1 | |||||
&ad_eval_sndfile, | |||||
&ad_open_sndfile, | |||||
&ad_close_sndfile, | |||||
&ad_info_sndfile, | |||||
&ad_seek_sndfile, | |||||
&ad_read_sndfile | |||||
#else | |||||
&ad_eval_null, | |||||
&ad_open_null, | |||||
&ad_close_null, | |||||
&ad_info_null, | |||||
&ad_seek_null, | |||||
&ad_read_null | |||||
#endif | |||||
}; | |||||
/* dlopen handler */ | |||||
const ad_plugin * adp_get_sndfile() { | |||||
return &ad_sndfile; | |||||
} |
@@ -1,95 +0,0 @@ | |||||
/* ffmpeg compatibility wrappers | |||||
* | |||||
* Copyright 2012,2013 Robin Gareus <robin@gareus.org> | |||||
* | |||||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
* of this software and associated documentation files (the "Software"), to deal | |||||
* in the Software without restriction, including without limitation the rights | |||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
* copies of the Software, and to permit persons to whom the Software is | |||||
* furnished to do so, subject to the following conditions: | |||||
* | |||||
* 1. Redistributions of source code must retain the above copyright notice, this | |||||
* list of conditions and the following disclaimer. | |||||
* 2. 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. | |||||
* | |||||
* 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 OWNER 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. | |||||
*/ | |||||
#ifndef FFCOMPAT_H | |||||
#define FFCOMPAT_H | |||||
#include <libavcodec/avcodec.h> | |||||
#include <libavformat/avformat.h> | |||||
#include <libavutil/avutil.h> | |||||
#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE | |||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 | |||||
#endif | |||||
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(50, 0, 0) | |||||
#define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO | |||||
#endif | |||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0) | |||||
static inline int avformat_open_input(AVFormatContext **ps, const char *filename, void *fmt, void **options) | |||||
{ | |||||
return av_open_input_file(ps, filename, NULL, 0, NULL); | |||||
} | |||||
#endif /* avformat < 53.2.0 */ | |||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 5, 0) | |||||
static inline AVCodecContext * | |||||
avcodec_alloc_context3(AVCodec *codec __attribute__((unused))) | |||||
{ | |||||
return avcodec_alloc_context(); | |||||
} | |||||
static inline AVStream * | |||||
avformat_new_stream(AVFormatContext *s, AVCodec *c) { | |||||
return av_new_stream(s,0); | |||||
} | |||||
static inline int | |||||
avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec) | |||||
{ | |||||
avcodec_get_context_defaults(s); | |||||
return 0; | |||||
} | |||||
#endif /* < 53.5.0 */ | |||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 5, 6) | |||||
static inline int | |||||
avcodec_open2(AVCodecContext *avctx, AVCodec *codec, void **options __attribute__((unused))) | |||||
{ | |||||
return avcodec_open(avctx, codec); | |||||
} | |||||
#endif /* <= 53.5.6 */ | |||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 5, 0) | |||||
static inline int | |||||
avformat_find_stream_info(AVFormatContext *ic, void **options) | |||||
{ | |||||
return av_find_stream_info(ic); | |||||
} | |||||
static inline void | |||||
avformat_close_input(AVFormatContext **s) | |||||
{ | |||||
av_close_input_file(*s); | |||||
} | |||||
#endif /* < 53.5.0 */ | |||||
#endif /* FFCOMPAT_H */ |
@@ -16,29 +16,11 @@ BUILD_CXX_FLAGS += -I. -I../../includes -I../../utils -I../distrho -isystem .. | |||||
ALL_C_FLAGS = $(BUILD_C_FLAGS) | ALL_C_FLAGS = $(BUILD_C_FLAGS) | ||||
# AudioFile | |||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
ALL_C_FLAGS += -DWANT_AUDIOFILE | |||||
endif | |||||
# MidiFile | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
ALL_C_FLAGS += -DWANT_MIDIFILE | |||||
endif | |||||
# ZynAddSubFX | # ZynAddSubFX | ||||
ifeq ($(HAVE_ZYN_DEPS),true) | ifeq ($(HAVE_ZYN_DEPS),true) | ||||
ALL_C_FLAGS += -DWANT_ZYNADDSUBFX | ALL_C_FLAGS += -DWANT_ZYNADDSUBFX | ||||
endif | endif | ||||
# -------------------------------------------------------------- | |||||
# Flags for MidiFile | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
MF_CXX_FLAGS = $(BUILD_CXX_FLAGS) | |||||
MF_CXX_FLAGS += $(shell pkg-config --cflags smf) | |||||
endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Flags for ZynAddSubFX | # Flags for ZynAddSubFX | ||||
@@ -71,6 +53,10 @@ OBJS += \ | |||||
midi-transpose.c.o \ | midi-transpose.c.o \ | ||||
nekofilter.c.o | nekofilter.c.o | ||||
OBJS += \ | |||||
audio-file.cpp.o \ | |||||
midi-file.cpp.o | |||||
ifneq ($(WIN32),true) | ifneq ($(WIN32),true) | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# External-UI plugins | # External-UI plugins | ||||
@@ -88,20 +74,6 @@ OBJS += \ | |||||
juce-patchbay.cpp.o | juce-patchbay.cpp.o | ||||
endif | endif | ||||
# -------------------------------------------------------------- | |||||
# AudioFile | |||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
OBJS += audio-file.cpp.o | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# MidiFile | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
OBJS += midi-file.cpp.o | |||||
endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# ZynAddSubFX | # ZynAddSubFX | ||||
@@ -195,7 +167,7 @@ juce-patchbay.cpp.o: juce-patchbay.cpp | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
midi-file.cpp.o: midi-file.cpp midi-base.hpp $(CXXDEPS) | midi-file.cpp.o: midi-file.cpp midi-base.hpp $(CXXDEPS) | ||||
$(CXX) $< $(MF_CXX_FLAGS) -c -o $@ | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
midi-sequencer.cpp.o: midi-sequencer.cpp midi-base.hpp $(CXXDEPS) | midi-sequencer.cpp.o: midi-sequencer.cpp midi-base.hpp $(CXXDEPS) | ||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
@@ -26,6 +26,12 @@ extern void carla_register_native_plugin_midithrough(); | |||||
extern void carla_register_native_plugin_miditranspose(); | extern void carla_register_native_plugin_miditranspose(); | ||||
extern void carla_register_native_plugin_nekofilter(); | extern void carla_register_native_plugin_nekofilter(); | ||||
// Audio File | |||||
extern void carla_register_native_plugin_audiofile(); | |||||
// MIDI File | |||||
extern void carla_register_native_plugin_midifile(); | |||||
#ifndef CARLA_OS_WIN | #ifndef CARLA_OS_WIN | ||||
// Carla | // Carla | ||||
extern void carla_register_native_plugin_carla(); | extern void carla_register_native_plugin_carla(); | ||||
@@ -42,19 +48,6 @@ extern void carla_register_native_plugin_vex_fx(); | |||||
extern void carla_register_native_plugin_vex_synth(); | extern void carla_register_native_plugin_vex_synth(); | ||||
#endif | #endif | ||||
#ifdef WANT_AUDIOFILE | |||||
// Audio File | |||||
extern void carla_register_native_plugin_audiofile(); | |||||
#endif | |||||
#ifdef WANT_MIDIFILE | |||||
// MIDI File | |||||
extern void carla_register_native_plugin_midifile(); | |||||
#endif | |||||
// SunVox File | |||||
extern void carla_register_native_plugin_sunvoxfile(); | |||||
#ifdef WANT_ZYNADDSUBFX | #ifdef WANT_ZYNADDSUBFX | ||||
// ZynAddSubFX | // ZynAddSubFX | ||||
extern void carla_register_native_plugin_zynaddsubfx_fx(); | extern void carla_register_native_plugin_zynaddsubfx_fx(); | ||||
@@ -72,6 +65,12 @@ void carla_register_all_plugins() | |||||
carla_register_native_plugin_miditranspose(); | carla_register_native_plugin_miditranspose(); | ||||
carla_register_native_plugin_nekofilter(); | carla_register_native_plugin_nekofilter(); | ||||
// Audio File | |||||
carla_register_native_plugin_audiofile(); | |||||
// MIDI File | |||||
carla_register_native_plugin_midifile(); | |||||
#ifndef CARLA_OS_WIN | #ifndef CARLA_OS_WIN | ||||
// Carla | // Carla | ||||
carla_register_native_plugin_carla(); | carla_register_native_plugin_carla(); | ||||
@@ -88,16 +87,6 @@ void carla_register_all_plugins() | |||||
carla_register_native_plugin_vex_synth(); | carla_register_native_plugin_vex_synth(); | ||||
#endif | #endif | ||||
#ifdef WANT_AUDIOFILE | |||||
// Audio File | |||||
carla_register_native_plugin_audiofile(); | |||||
#endif | |||||
#ifdef WANT_MIDIFILE | |||||
// MIDI File | |||||
carla_register_native_plugin_midifile(); | |||||
#endif | |||||
#ifdef WANT_ZYNADDSUBFX | #ifdef WANT_ZYNADDSUBFX | ||||
// ZynAddSubFX | // ZynAddSubFX | ||||
carla_register_native_plugin_zynaddsubfx_fx(); | carla_register_native_plugin_zynaddsubfx_fx(); | ||||
@@ -69,10 +69,6 @@ LIBS += ../modules/juce_audio_basics.a | |||||
LIBS += ../modules/juce_core.a | LIBS += ../modules/juce_core.a | ||||
LIBS += ../modules/rtmempool.a | LIBS += ../modules/rtmempool.a | ||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
LIBS += ../modules/audio_decoder.a | |||||
endif | |||||
ifeq ($(HAVE_JUCE_UI),true) | ifeq ($(HAVE_JUCE_UI),true) | ||||
LIBS += ../modules/juce_audio_processors.a | LIBS += ../modules/juce_audio_processors.a | ||||
LIBS += ../modules/juce_data_structures.a | LIBS += ../modules/juce_data_structures.a | ||||