Added a C-style interface header and wrapper for projectM.

This will make it easier to integrate projectM into C applications and also removes potential issues of STL/C++ version differences between host and library.

Changed visibility of all symbols except the C API to "hidden". This effectively prevents the C++ API from being used in the shared library.

Added an option "ENABLE_CXX_INTERFACE" to re-enable the old export behaviour, displaying a prominent author warning after configuring the build if enabled.
This commit is contained in:
Kai Blaschke
2021-08-17 00:06:02 +02:00
parent a9be845e2d
commit 14f4bcac65
10 changed files with 1564 additions and 9 deletions

View File

@ -37,6 +37,7 @@ set(PROJECTM_LIB_DIR "lib" CACHE STRING "Library installation directory, relativ
set(PROJECTM_INCLUDE_DIR "include" CACHE STRING "Header installation directory, relative to the install prefix.")
# Feature options, including dependencies.
option(ENABLE_CXX_INTERFACE "Enable exporting all C++ symbols, not only the C API, in the shared library. Warning: This is dangerous!" OFF)
option(ENABLE_PRESETS "Build and install bundled presets" ON)
option(ENABLE_NATIVE_PRESETS "Build and install native libraries written in C/C++" OFF)
option(ENABLE_TESTING "Build and install the projectM test suite" OFF)
@ -161,6 +162,16 @@ if(ENABLE_LIBVISUAL)
set(PROJECTM_LIBVISUAL_DIR "${LIBVISUAL_PLUGINSBASEDIR}/actor" CACHE STRING "Installation directory for the libvisual plug-in library.")
endif()
if(ENABLE_CXX_INTERFACE)
set(CMAKE_C_VISIBILITY_PRESET default)
set(CMAKE_CXX_VISIBILITY_PRESET default)
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
else()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
endif()
include(features.cmake)
add_subdirectory(presets)
@ -224,6 +235,15 @@ message(AUTHOR_WARNING
"DO NOT base any production work on it yet!\n"
)
if(ENABLE_CXX_INTERFACE)
message(AUTHOR_WARNING "This build is configured to export all C++ symbols in the shared library.\n"
"Using C++ STL types across library borders only works if all components were built "
"with the exact same toolchain and C++ language level, otherwise it will cause crashes.\n"
"Enabling this option will not export additional symbols in Windows DLL builds.\n"
"Only use this if you know what you're doing. You have been warned!"
)
endif()
# Create CPack configuration
set(CPACK_PACKAGE_NAME "projectM")
set(CPACK_VERBATIM_VARIABLES YES)

View File

@ -67,8 +67,11 @@ add_library(projectM_main OBJECT
PresetLoader.cpp
PresetLoader.hpp
projectM.cpp
projectM.h
projectM.hpp
projectM-opengl.h
ProjectMCWrapper.cpp
ProjectMCWrapper.hpp
RandomNumberGenerators.hpp
resource.h
sdltoprojectM.h
@ -84,6 +87,8 @@ add_library(projectM_main OBJECT
target_include_directories(projectM_main
PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/include"
"${CMAKE_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/Renderer"
"${CMAKE_CURRENT_SOURCE_DIR}/Renderer/hlslparser/src"
@ -99,6 +104,13 @@ target_link_libraries(projectM_main
${PROJECTM_OPENGL_LIBRARIES}
)
include(GenerateExportHeader)
generate_export_header(projectM_main
BASE_NAME projectM
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/libprojectM/projectM_export.h"
)
add_library(projectM_static STATIC
# Xcode needs at least one source file, otherwise it won't create the static library.
StaticLibDummy.cpp
@ -244,7 +256,9 @@ install(FILES
dlldefs.h
event.h
fatal.h
projectM.h
projectM.hpp
"${CMAKE_CURRENT_BINARY_DIR}/include/libprojectM/projectM_export.h"
DESTINATION "${PROJECTM_INCLUDE_DIR}/libprojectM"
COMPONENT Devel
)

View File

@ -157,7 +157,7 @@ const std::vector<std::string> &PresetLoader::getPresetNames() const
}
// Get the preset index given a name
const unsigned int PresetLoader::getPresetIndex(std::string &name) const
unsigned int PresetLoader::getPresetIndex(const std::string& name) const
{
return find(_presetNames.begin(), _presetNames.end(), name) - _presetNames.begin();
}

View File

@ -74,7 +74,7 @@ class PresetLoader {
const std::vector<std::string> & getPresetNames() const;
/// Get the preset index given a name
const unsigned int getPresetIndex(std::string &name) const;
unsigned int getPresetIndex(const std::string& name) const;
/// Returns the number of presets in the active directory
inline std::size_t size() const {

View File

@ -0,0 +1,631 @@
#include "ProjectMCWrapper.hpp"
#include "projectM.h"
#include <cstring>
#include <utility>
projectMWrapper::projectMWrapper(std::string configFile, int flags)
: projectM(std::move(configFile), flags)
{
}
projectMWrapper::projectMWrapper(projectM::Settings settings, int flags)
: projectM(std::move(settings), flags)
{
}
void projectMWrapper::presetSwitchedEvent(bool isHardCut, size_t presetIndex) const
{
if (_presetSwitchedEventCallback)
{
_presetSwitchedEventCallback(isHardCut, presetIndex);
}
}
void projectMWrapper::shuffleEnabledValueChanged(bool shuffle_enabled) const
{
if (_shuffleEnableChangedEventCallback)
{
_shuffleEnableChangedEventCallback(shuffle_enabled);
}
}
void projectMWrapper::presetSwitchFailedEvent(bool isHardCut, unsigned int presetIndex,
const std::string& failureMessage) const
{
if (_presetSwitchFailedEventCallback)
{
_presetSwitchFailedEventCallback(isHardCut, presetIndex, failureMessage.c_str());
}
}
void projectMWrapper::presetRatingChanged(unsigned int presetIndex, int rating, PresetRatingType ratingType) const
{
if (_presetRatingChangedEventCallback)
{
_presetRatingChangedEventCallback(presetIndex, rating, static_cast<projectm_preset_rating_type>(ratingType));
}
}
projectMWrapper* handle_to_instance(projectm_handle instance)
{
return reinterpret_cast<projectMWrapper*>(instance);
}
char* projectm_alloc_string(unsigned int length)
{
try
{
return new char[length]{};
}
catch (...)
{
return nullptr;
}
}
char* projectm_alloc_string_from_std_string(const std::string& str)
{
auto pointer = projectm_alloc_string(str.length() + 1);
if (pointer)
{
memcpy(pointer, str.c_str(), str.length());
}
return pointer;
}
void projectm_free_string(const char* str)
{
delete[] str;
}
projectm_settings_t* projectm_alloc_settings()
{
try
{
return new projectm_settings_t{};
}
catch (...)
{
return nullptr;
}
}
void projectm_free_settings(projectm_settings_t* settings)
{
if (settings)
{
projectm_free_string(settings->preset_url);
projectm_free_string(settings->title_font_url);
projectm_free_string(settings->menu_font_url);
projectm_free_string(settings->data_dir);
}
delete settings;
}
projectm_handle projectm_create(const char* setting_file_path, int flags)
{
try
{
auto projectMInstance = new projectMWrapper(std::string(setting_file_path), flags);
return reinterpret_cast<projectm_handle>(projectMInstance);
}
catch (...)
{
return nullptr;
}
}
projectm_handle projectm_create_settings(const projectm_settings_t* settings, int flags)
{
try
{
projectM::Settings cppSettings;
cppSettings.meshX = settings->mesh_x;
cppSettings.meshY = settings->mesh_y;
cppSettings.fps = settings->fps;
cppSettings.textureSize = settings->texture_size;
cppSettings.windowWidth = settings->window_width;
cppSettings.windowHeight = settings->window_height;
cppSettings.presetURL = settings->preset_url ? settings->preset_url : "";
cppSettings.titleFontURL = settings->title_font_url ? settings->title_font_url : "";
cppSettings.menuFontURL = settings->menu_font_url ? settings->menu_font_url : "";
cppSettings.datadir = settings->data_dir ? settings->data_dir : "";
cppSettings.smoothPresetDuration = settings->smooth_preset_duration;
cppSettings.presetDuration = settings->preset_duration;
cppSettings.hardcutEnabled = settings->hardcut_enabled;
cppSettings.hardcutDuration = settings->hardcut_duration;
cppSettings.hardcutSensitivity = settings->hardcut_sensitivity;
cppSettings.beatSensitivity = settings->beat_sensitivity;
cppSettings.aspectCorrection = settings->aspect_correction;
cppSettings.easterEgg = settings->easter_egg;
cppSettings.shuffleEnabled = settings->shuffle_enabled;
cppSettings.softCutRatingsEnabled = settings->soft_cut_ratings_enabled;
auto projectMInstance = new projectMWrapper(cppSettings, flags);
return reinterpret_cast<projectm_handle>(projectMInstance);
}
catch (...)
{
return nullptr;
}
}
void projectm_destroy(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
delete projectMInstance;
}
void projectm_set_preset_switched_event_callback(projectm_handle instance, projectm_preset_switched_event callback)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->_presetSwitchedEventCallback = callback;
}
void projectm_set_shuffle_enable_changed_event_callback(projectm_handle instance,
projectm_shuffle_enable_changed_event callback)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->_shuffleEnableChangedEventCallback = callback;
}
void projectm_set_preset_switch_failed_event_callback(projectm_handle instance,
projectm_preset_switch_failed_event callback)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->_presetSwitchFailedEventCallback = callback;
}
void projectm_set_preset_rating_changed_event_callback(projectm_handle instance,
projectm_preset_rating_changed_event callback)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->_presetRatingChangedEventCallback = callback;
}
void projectm_reset_gl(projectm_handle instance, int width, int height)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->projectM_resetGL(width, height);
}
void projectm_reset_textures(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->projectM_resetTextures();
}
void projectm_set_title(projectm_handle instance, const char* title)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->projectM_setTitle(title);
}
void projectm_render_frame(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->renderFrame();
}
unsigned int projectm_init_render_to_texture(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->initRenderToTexture();
}
void projectm_key_handler(projectm_handle instance, projectMEvent event, projectMKeycode keycode,
projectMModifier modifier)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->key_handler(event, keycode, modifier);
}
void projectm_default_key_handler(projectm_handle instance, projectMEvent event, projectMKeycode keycode)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->default_key_handler(event, keycode);
}
void projectm_set_texture_size(projectm_handle instance, int size)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->changeTextureSize(size);
}
void projectm_set_hardcut_duration(projectm_handle instance, double seconds)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->changeHardcutDuration(seconds);
}
void projectm_set_preset_duration(projectm_handle instance, double seconds)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->changePresetDuration(seconds);
}
void projectm_get_mesh_size(projectm_handle instance, int* width, int* height)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->getMeshSize(width, height);
}
void projectm_touch(projectm_handle instance, float x, float y, int pressure, projectm_touch_type touch_type)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->touch(x, y, pressure, touch_type);
}
void projectm_touch_drag(projectm_handle instance, float x, float y, int pressure)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->touchDrag(x, y, pressure);
}
void projectm_touch_destroy(projectm_handle instance, float x, float y)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->touchDestroy(x, y);
}
void projectm_touch_destroy_all(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->touchDestroyAll();
}
void projectm_set_help_text(projectm_handle instance, const char* help_text)
{
if (!help_text)
{
return;
}
auto projectMInstance = handle_to_instance(instance);
projectMInstance->setHelpText(help_text);
}
void projectm_set_toast_message(projectm_handle instance, const char* toast_message)
{
if (!toast_message)
{
return;
}
auto projectMInstance = handle_to_instance(instance);
projectMInstance->setToastMessage(toast_message);
}
projectm_settings_t* projectm_get_settings(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
const auto& settings = projectMInstance->settings();
auto settingsStruct = projectm_alloc_settings();
settingsStruct->mesh_x = settings.meshX;
settingsStruct->mesh_y = settings.meshY;
settingsStruct->fps = settings.fps;
settingsStruct->texture_size = settings.textureSize;
settingsStruct->window_width = settings.windowWidth;
settingsStruct->window_height = settings.windowHeight;
settingsStruct->preset_url = projectm_alloc_string_from_std_string(settings.presetURL);
settingsStruct->title_font_url = projectm_alloc_string_from_std_string(settings.titleFontURL);
settingsStruct->menu_font_url = projectm_alloc_string_from_std_string(settings.menuFontURL);
settingsStruct->data_dir = projectm_alloc_string_from_std_string(settings.datadir);
settingsStruct->smooth_preset_duration = settings.smoothPresetDuration;
settingsStruct->preset_duration = settings.presetDuration;
settingsStruct->hardcut_enabled = settings.hardcutEnabled;
settingsStruct->hardcut_duration = settings.hardcutDuration;
settingsStruct->hardcut_sensitivity = settings.hardcutSensitivity;
settingsStruct->beat_sensitivity = settings.beatSensitivity;
settingsStruct->aspect_correction = settings.aspectCorrection;
settingsStruct->easter_egg = settings.easterEgg;
settingsStruct->shuffle_enabled = settings.shuffleEnabled;
settingsStruct->soft_cut_ratings_enabled = settings.softCutRatingsEnabled;
return settingsStruct;
}
void projectm_write_config(const char* config_file, const projectm_settings_t* settings)
{
projectM::Settings cppSettings;
cppSettings.meshX = settings->mesh_x;
cppSettings.meshY = settings->mesh_y;
cppSettings.fps = settings->fps;
cppSettings.textureSize = settings->texture_size;
cppSettings.windowWidth = settings->window_width;
cppSettings.windowHeight = settings->window_height;
cppSettings.presetURL = settings->preset_url ? settings->preset_url : "";
cppSettings.titleFontURL = settings->title_font_url ? settings->title_font_url : "";
cppSettings.menuFontURL = settings->menu_font_url ? settings->menu_font_url : "";
cppSettings.datadir = settings->data_dir ? settings->data_dir : "";
cppSettings.smoothPresetDuration = settings->smooth_preset_duration;
cppSettings.presetDuration = settings->preset_duration;
cppSettings.hardcutEnabled = settings->hardcut_enabled;
cppSettings.hardcutDuration = settings->hardcut_duration;
cppSettings.hardcutSensitivity = settings->hardcut_sensitivity;
cppSettings.beatSensitivity = settings->beat_sensitivity;
cppSettings.aspectCorrection = settings->aspect_correction;
cppSettings.easterEgg = settings->easter_egg;
cppSettings.shuffleEnabled = settings->shuffle_enabled;
cppSettings.softCutRatingsEnabled = settings->soft_cut_ratings_enabled;
projectM::writeConfig(config_file, cppSettings);
}
void projectm_select_preset_position(projectm_handle instance, unsigned int index)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->selectPresetPosition(index);
}
void projectm_select_preset(projectm_handle instance, unsigned int index, bool hard_cut)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->selectPreset(index, hard_cut);
}
void projectm_populate_preset_menu(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->populatePresetMenu();
}
void projectm_remove_preset(projectm_handle instance, unsigned int index)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->removePreset(index);
}
void projectm_clear_playlist(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->clearPlaylist();
}
void projectm_lock_preset(projectm_handle instance, bool lock)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->setPresetLock(lock);
}
bool projectm_is_text_input_active(projectm_handle instance, bool no_minimum_length)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->isTextInputActive(no_minimum_length);
}
unsigned int projectm_get_preset_index(projectm_handle instance, const char* preset_name)
{
if (!preset_name)
{
return 0;
}
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getPresetIndex(preset_name);
}
void projectm_select_preset_by_name(projectm_handle instance, const char* preset_name, bool hard_cut)
{
if (!preset_name)
{
return;
}
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->selectPresetByName(preset_name, hard_cut);
}
void projectm_set_search_text(projectm_handle instance, const char* search_text)
{
if (!search_text)
{
return;
}
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->setSearchText(search_text);
}
void projectm_delete_search_text(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->deleteSearchText();
}
void projectm_reset_search_text(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->resetSearchText();
}
bool projectm_selected_preset_index(projectm_handle instance, unsigned int* index)
{
if (!index)
{
return false;
}
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->selectedPresetIndex(*index);
}
void projectm_add_preset_url(projectm_handle instance, const char* preset_url, const char* preset_name,
int* rating_list, unsigned int rating_list_length)
{
if (!preset_url
|| !preset_name
|| (!rating_list && rating_list_length > 0)
|| rating_list_length != TOTAL_RATING_TYPES)
{
return;
}
RatingList ratingList;
for (unsigned int ratingIndex = 0; ratingIndex < rating_list_length; ratingIndex++)
{
ratingList.push_back(rating_list[ratingIndex]);
}
auto projectMInstance = handle_to_instance(instance);
projectMInstance->addPresetURL(preset_url, preset_name, ratingList);
}
void projectm_insert_preset_url(projectm_handle instance, unsigned int index, const char* preset_url,
const char* preset_name, int* rating_list, unsigned int rating_list_length)
{
if (!preset_url
|| !preset_name
|| (!rating_list && rating_list_length > 0)
|| rating_list_length != TOTAL_RATING_TYPES)
{
return;
}
RatingList ratingList;
for (unsigned int ratingIndex = 0; ratingIndex < rating_list_length; ratingIndex++)
{
ratingList.push_back(rating_list[ratingIndex]);
}
auto projectMInstance = handle_to_instance(instance);
projectMInstance->insertPresetURL(index, preset_url, preset_name, ratingList);
}
bool projectm_preset_position_valid(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->presetPositionValid();
}
const char* projectm_get_preset_url(projectm_handle instance, unsigned int index)
{
auto projectMInstance = handle_to_instance(instance);
return projectm_alloc_string_from_std_string(projectMInstance->getPresetURL(index));
}
const char* projectm_get_preset_name(projectm_handle instance, unsigned int index)
{
auto projectMInstance = handle_to_instance(instance);
return projectm_alloc_string_from_std_string(projectMInstance->getPresetName(index));
}
void projectm_change_preset_name(projectm_handle instance, unsigned int index, const char* name)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->changePresetName(index, name);
}
int projectm_get_preset_rating(projectm_handle instance, unsigned int index, projectm_preset_rating_type rating_type)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getPresetRating(index, static_cast<PresetRatingType>(rating_type));
}
void projectm_change_preset_rating(projectm_handle instance, unsigned int index, int rating,
projectm_preset_rating_type rating_type)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->changePresetRating(index, rating, static_cast<PresetRatingType>(rating_type));
}
unsigned int projectm_get_playlist_size(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getPlaylistSize();
}
void projectm_set_shuffle_enabled(projectm_handle instance, bool shuffle_enabled)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->setShuffleEnabled(shuffle_enabled);
}
bool projectm_is_shuffle_enabled(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->isShuffleEnabled();
}
unsigned int projectm_get_search_index(projectm_handle instance, const char* name)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getSearchIndex(name);
}
void projectm_select_previous(projectm_handle instance, bool hard_cut)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->selectPrevious(hard_cut);
}
void projectm_select_next(projectm_handle instance, bool hard_cut)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->selectNext(hard_cut);
}
void projectm_select_random(projectm_handle instance, bool hard_cut)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->selectRandom(hard_cut);
}
int projectm_get_window_width(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getWindowWidth();
}
int projectm_get_window_height(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getWindowHeight();
}
bool projectm_get_error_loading_current_preset(projectm_handle instance)
{
auto projectMInstance = handle_to_instance(instance);
return projectMInstance->getErrorLoadingCurrentPreset();
}
void projectm_pcm_add_float_1ch_data(projectm_handle instance, const float* pcm_data, unsigned int sample_count)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCMfloat(pcm_data, sample_count);
}
void projectm_pcm_add_float_2ch_data(projectm_handle instance, const float* pcm_data, unsigned int sample_count)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCMfloat_2ch(pcm_data, sample_count);
}
void projectm_pcm_add_16bit_2ch_512(projectm_handle instance, const short (* pcm_data)[512])
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCM16(pcm_data);
}
void projectm_pcm_add_16bit_2ch_data(projectm_handle instance, const short* pcm_data, unsigned int sample_count)
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCM16Data(pcm_data, sample_count);
}
void projectm_pcm_add_8bit_2ch_1024(projectm_handle instance, const unsigned char (* pcm_data)[1024])
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCM8(pcm_data);
}
void projectm_pcm_add_8bit_2ch_512(projectm_handle instance, const unsigned char (* pcm_data)[512])
{
auto projectMInstance = handle_to_instance(instance);
projectMInstance->pcm()->addPCM8_512(pcm_data);
}

View File

@ -0,0 +1,50 @@
/*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2021 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "projectM.hpp"
extern "C" {
#include "projectM.h"
}
class projectMWrapper : public projectM
{
public:
projectMWrapper(std::string configFile, int flags);
projectMWrapper(Settings settings, int flags);
void presetSwitchedEvent(bool isHardCut, size_t presetIndex) const override;
void shuffleEnabledValueChanged(bool shuffle_enabled) const override;
void presetSwitchFailedEvent(bool isHardCut, unsigned int presetIndex,
const std::string& failureMessage) const override;
void presetRatingChanged(unsigned int presetIndex, int rating, PresetRatingType ratingType) const override;
projectm_preset_switched_event _presetSwitchedEventCallback{ nullptr };
projectm_shuffle_enable_changed_event _shuffleEnableChangedEventCallback{ nullptr };
projectm_preset_switch_failed_event _presetSwitchFailedEventCallback{ nullptr };
projectm_preset_rating_changed_event _presetRatingChangedEventCallback{ nullptr };
};

View File

@ -12,7 +12,14 @@
enum MilkdropWaveformMode
{
Circle=0, RadialBlob, Blob2, Blob3, DerivativeLine, Blob5, Line, DoubleLine,
Circle = 1,
RadialBlob,
Blob2,
Blob3,
DerivativeLine,
Blob5,
Line,
DoubleLine,
last // last is a placeholder to find enum size. Please ignore and leave this here.
};

View File

@ -1146,7 +1146,7 @@ void projectM::toggleSearchText()
}
// get index from search results based on preset name
unsigned int projectM::getSearchIndex(std::string &name) const
unsigned int projectM::getSearchIndex(const std::string& name) const
{
for (auto& it : renderer->m_presetList) {
if (it.name == name) return it.id;
@ -1155,7 +1155,7 @@ unsigned int projectM::getSearchIndex(std::string &name) const
}
// get preset index based on preset name
unsigned int projectM::getPresetIndex(std::string& name) const
unsigned int projectM::getPresetIndex(const std::string& name) const
{
return m_presetLoader->getPresetIndex(name);
}

833
src/libprojectM/projectM.h Normal file
View File

@ -0,0 +1,833 @@
/*
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2021 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
#pragma once
#include "libprojectM/projectM_export.h"
#include "libprojectM/event.h"
struct projectm; //!< Opaque projectM instance type.
typedef projectm* projectm_handle; //!< A pointer to the opaque projectM instance.
/**
* @brief projectM instance settings.
*
* <p>Use this struct to provide settings for projectM, for example if your application handles projectM configuration
* internally instead of using the default configuration file.</p>
*
* <p>Always allocate the struct using the projectm_alloc_settings() and free it with the projectm_free_settings()
* function.</p>
*
* <p>To allocate memory for char* members, always use projectm_alloc_string(). If any pointer is not NULL,
* projectm_free_settings() will automatically call projectm_free_string() on it. If you free it on your own, remember
* to reset the pointer to NULL after doing so!</p>
*/
typedef struct projectm_settings
{
int mesh_x; //!< Per-pixel mesh X resolution.
int mesh_y; //!< Per-pixel mesh Y resolution.
int fps; //!< Target rendering frames per second.
int texture_size; //!< Size of the render texture. Must be a power of 2.
int window_width; //!< Width of the rendering viewport.
int window_height; //!< Height of the rendering viewport.
char* preset_url; //!< Path to a preset playlist in XML format to be loaded. Use FLAG_DISABLE_PLAYLIST_LOAD to skip loading a playlist.
char* title_font_url; //!< Path to the "title" font that is used to render the preset name.
char* menu_font_url; //!< Path to the "menu" font that is used to render the built-in on-screen menu.
char* data_dir; //!< Path to data files like default fonts and presets.
double smooth_preset_duration; //!< Blend-over duration between two presets in seconds.
double preset_duration; //!< Display duration for each preset in seconds.
bool hardcut_enabled; //!< Set to true to enable fast beat-driven preset switches.
int hardcut_duration; //!< Minimum time a preset is displayed before a hardcut can happen in seconds.
float hardcut_sensitivity; //!< Beat sensitivity value that must be surpassed for a hardcut.
float beat_sensitivity; //!< Beat sensitivity. Standard sensitivity is 1.0.
bool aspect_correction; //!< Use aspect ration correction in presets that support it.
float easter_egg; //!< Used as the "sigma" value for a gaussian RNG to randomize preset duration. Unused on Windows.
bool shuffle_enabled; //!< Enable playlist shuffle, selecting a random preset on each switch instead of the next in list.
bool soft_cut_ratings_enabled; //!< If true, use soft cut ratings on soft cuts and hard cut ratings on hard cuts. If false, the hard cut rating is always used.
} projectm_settings_t;
/**
* Flags that influence projectM instance creation.
*/
enum projectm_flags
{
PROJECTM_FLAG_NONE = 0, //!< No flags.
PROJECTM_FLAG_DISABLE_PLAYLIST_LOAD = 1 << 0 //!< Set this flag to disable loading a preset playlist on startup.
};
/**
* Rating types supported by projectM. Used to control preset selection for different types
* of transitions (hard/soft).
*/
enum projectm_preset_rating_type
{
PROJECTM_HARD_CUT_RATING_TYPE, //!< Rating for hard cuts.
PROJECTM_SOFT_CUT_RATING_TYPE //!< Rating for soft cuts.
};
/**
* Placeholder values that can be used to address channel indices in PCM data arrays.
*/
enum projectm_pcm_channel
{
PROJECTM_CHANNEL_L = 0, //!< Left audio channel.
PROJECTM_CHANNEL_0 = 0, //!< Left audio channel.
PROJECTM_CHANNEL_R = 1, //!< Right audio channel.
PROJECTM_CHANNEL_1 = 1 //!< Right audio channel.
};
/**
* Waveform render types used in the touch start method.
*/
enum projectm_touch_type
{
PROJECTM_TOUCH_TYPE_RANDOM, //!< Random waveform type.
PROJECTM_TOUCH_TYPE_CIRCLE, //!< Draws a circular waveform.
PROJECTM_TOUCH_TYPE_RADIAL_BLOB, //!< Draws a radial blob waveform.
PROJECTM_TOUCH_TYPE_BLOB2,//!< Draws a blob-style waveform.
PROJECTM_TOUCH_TYPE_BLOB3, //!< Draws another blob-style waveform.
PROJECTM_TOUCH_TYPE_DERIVATIVE_LINE, //!< Draws a derivative-line waveform.
PROJECTM_TOUCH_TYPE_BLOB5, //!< Draws a five-blob waveform.
PROJECTM_TOUCH_TYPE_LINE, //!< Draws a single-line waveform.
PROJECTM_TOUCH_TYPE_DOUBLE_LINE //!< Draws a double-line waveform.
};
/**
* @brief Allocates memory for a string and returns the pointer.
*
* To free the allocated memory, call projectm_free_string(). Do not use free()!
*
* @return A pointer to a zero-initialized memory area.
*/
PROJECTM_EXPORT char* projectm_alloc_string(unsigned int length);
/**
* @brief Frees the memory of an allocated string.
*
* Frees the memory allocated by a call to projectm_alloc_string() or any
* (const) char* pointers returned by an API call.
*
* Do not use free() to delete the pointer!
*
* @param settings A pointer returned by projectm_alloc_string().
*/
PROJECTM_EXPORT void projectm_free_string(const char* str);
/**
* @brief Allocates memory for a projectm_settings_t struct and returns the pointer.
*
* To free the allocated memory, call projectm_free_settings(). Do not use free()!
*
* @return A pointer to a zero-initialized projectm_settings_t struct.
*/
PROJECTM_EXPORT projectm_settings_t* projectm_alloc_settings();
/**
* @brief Frees the memory of an allocated projectm_settings_t structure.
*
* Frees the memory allocated by a call to projectm_alloc_settings() or any
* projectm_settings_t* returned by an API call.
*
* Do not use free() to delete the pointer!
*
* @param settings A pointer returned by projectm_alloc_settings().
*/
PROJECTM_EXPORT void projectm_free_settings(const projectm_settings_t* settings);
/**
* @brief Callback function that is executed on each preset change.
*
* Can be used for example to update the application window title.
*
* @param is_hard_cut True if the preset was switched using a hard cut via beat detection.
* @param index The playlist index of the new preset.
*/
typedef void(* projectm_preset_switched_event)(bool is_hard_cut, unsigned int index);
/**
* @brief Callback function that is executed is the shuffle setting has changed.
* @param shuffle_enabled True if shuffle is enabled, false if it was disabled.
*/
typedef void(* projectm_shuffle_enable_changed_event)(bool shuffle_enabled);
/**
* @brief Callback function that is executed if a preset change failed.
*
* The message pointer is only valid inside the callback. Make a copy if it must be kept
* for later use.
*
* @param is_hard_cut True if the preset was switched using a hard cut via beat detection.
* @param index The playlist index of the new preset.
* @param message The error message.
*/
typedef void(* projectm_preset_switch_failed_event)(bool is_hard_cut, unsigned int index, const char* message);
/**
* @brief Callback function that is executed if a preset rating has been changed.
*
* Can be used for example to update the rating display in the host application.
*
* @param index The playlist index of the new preset.
* @param rating The new rating value.
* @param rating_type The rating type that has been changed.
*/
typedef void(* projectm_preset_rating_changed_event)(unsigned int index, int rating,
projectm_preset_rating_type rating_type);
/**
* @brief Creates a new projectM instance, reading settings from the given file.
* @param setting_file_path A path to the settings file to read the configuration from.
* If NULL or an empty path are provided, default settings will be used.
* @param flags Any combination of values from the projectm_flags enumeration.
* @return A projectM handle for the newly created instance that must be used in subsequent API calls.
* NULL if the instance could not be created successfully.
*/
PROJECTM_EXPORT projectm_handle projectm_create(const char* setting_file_path, int flags);
/**
* @brief Creates a new projectM instance, reading settings from the given file.
* @param settings A pointer to a projectm_settings_t with the settings to be used by the new instance.
* If this pointer is NULL, default settings will be used.
* @param flags Any combination of values from the projectm_flags enumeration.
* @return A projectM handle for the newly created instance that must be used in subsequent API calls.
* NULL if the instance could not be created successfully.
*/
PROJECTM_EXPORT projectm_handle projectm_create_settings(projectm_settings_t* settings, int flags);
/**
* @brief Destroys the given instance and frees the resources.
*
* After destroying the handle, it must not be used for any other calls to the API.
*
* @param instance A handle returned by projectm_create() or projectm_create_settings().
*/
PROJECTM_EXPORT void projectm_destroy(projectm_handle instance);
/**
* @brief Sets a callback function that will be called when a preset changes.
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
*/
PROJECTM_EXPORT void projectm_set_preset_switched_event_callback(projectm_handle instance,
projectm_preset_switched_event callback);
/**
* @brief Sets a callback function that will be called when the shuffle setting changes.
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
*/
PROJECTM_EXPORT void projectm_set_shuffle_enable_changed_event_callback(projectm_handle instance,
projectm_shuffle_enable_changed_event callback);
/**
* @brief Sets a callback function that will be called when a preset change failed.
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
*/
PROJECTM_EXPORT void projectm_set_preset_switch_failed_event_callback(projectm_handle instance,
projectm_preset_switch_failed_event callback);
/**
* @brief Sets a callback function that will be called when a preset rating changed.
* @param instance The projectM instance handle.
* @param callback A pointer to the callback function.
*/
PROJECTM_EXPORT void projectm_set_preset_rating_changed_event_callback(projectm_handle instance,
projectm_preset_rating_changed_event callback);
/**
* @brief Reset the projectM OpenGL renderer.
*
* Required if anything invalidates the state of the current OpenGL context projectM is rendering to.
* This is the case on window resizes, restoring a window from minimized state or other events that
* required recreating of OpenGL objects.
*
* @param instance The projectM instance handle.
* @param width The rendering viewport width.
* @param height The rendering viewport height.
*/
PROJECTM_EXPORT void projectm_reset_gl(projectm_handle instance, int width, int height);
/**
* @brief Reloads all textures.
*
* Also resets the OpenGL renderer without changing the viewport size. Useful if preset paths were changed.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_reset_textures(projectm_handle instance);
/**
* @brief Sets the current title text and displays it.
* @param instance The projectM instance handle.
* @param title The title text to display.
*/
PROJECTM_EXPORT void projectm_set_title(projectm_handle instance, const char* title);
/**
* @brief Renders a single frame.
*
* @note Separate two-pass frame rendering is currently not supported by the C API as it is rarely used
* and also depends on the loaded preset.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_render_frame(projectm_handle instance);
/**
* @brief Enables render-to-texture.
*
* Useful if projectM output will be part of a more complex OpenGL scene. The size of the texture is determined by the
* given viewport size and the dimensions should be a power of 2.
*
* @param instance The projectM instance handle.
* @return A GLuint value with the texture ID projectM will render to.
*/
PROJECTM_EXPORT unsigned int projectm_init_render_to_texture(projectm_handle instance);
/**
* @brief Key handler that processes user input.
*
* This method can be used to send user input in the host application to projectM, for example
* to switch presets, display the help and search menus or change settings like beat sensitivity.
*
* All actions executed by the key handler can also be run programmatically if the host application
* is not able to redirect keyboard input to projectM.
*
* @param instance The projectM instance handle.
* @param event The key event, valid are either PROJECTM_KEYUP or PROJECTM_KEYDOWN.
* @param keycode The key code, mapped to a value of the projectMKeycode enumeration.
* @param modifier The key modifier as a value from the projectMModifier.
*/
PROJECTM_EXPORT void projectm_key_handler(projectm_handle instance, projectMEvent event,
projectMKeycode keycode, projectMModifier modifier);
/**
* @brief Default key handler that processes user input.
*
* This method can be used to send user input in the host application to projectM, for example
* to switch presets, display the help and search menus or change settings like beat sensitivity.
*
* All actions executed by the key handler can also be run programmatically if the host application
* is not able to redirect keyboard input to projectM.
*
* @param instance The projectM instance handle.
* @param event The key event, valid are either PROJECTM_KEYUP or PROJECTM_KEYDOWN.
* @param keycode The key code, mapped to a value of the projectMKeycode enumeration.
*/
PROJECTM_EXPORT void projectm_default_key_handler(projectm_handle instance, projectMEvent event,
projectMKeycode keycode);
/**
* @brief Changes the size of the internal render texture.
* @note This will recreate the internal renderer.
* @param instance The projectM instance handle.
* @param size The new size of the render texture. Must be a power of 2.
*/
PROJECTM_EXPORT void projectm_set_texture_size(projectm_handle instance, int size);
/**
* @brief Sets the minimum display time before a hard cut can happen.
*
* <p>Hard cuts are beat-sensitive preset transitions, immediately changing from
* one preset to the next without a smooth blending period.</p>
*
* <p>Set this to a higher value than preset duration to disable hard cuts.</p>
*
* @param instance The projectM instance handle.
* @param seconds Minimum number of seconds the preset will be displayed before a hard cut.
*/
PROJECTM_EXPORT void projectm_set_hardcut_duration(projectm_handle instance, double seconds);
/**
* @brief Sets the preset display duration before switching to the next using a soft cut.
* @param instance The projectM instance handle.
* @param seconds The number of seconds a preset will be displayed before the next is shown.
*/
PROJECTM_EXPORT void projectm_set_preset_duration(projectm_handle instance, double seconds);
/**
* @brief returns the per-pixel equation mesh size in units.
* @param instance The projectM instance handle.
* @param width The width of the mesh.
* @param height The height of the mesh.
*/
PROJECTM_EXPORT void projectm_get_mesh_size(projectm_handle instance, int* width, int* height);
/**
* @brief Starts a touch event or moves an existing waveform.
*
* This will add or move waveforms in addition to the preset waveforms. If there is an existing waveform
* at the given coordinates, it will be centered on the new coordinates. If there is no waveform, a new one
* will be added.
*
* @param instance The projectM instance handle.
* @param x The x coordinate of the touch event.
* @param y The y coordinate of the touch event.
* @param pressure The amount of pressure applied in a range from 0.0 to 1.0.
* @param touch_type The waveform type that will be rendered on touch.
*/
PROJECTM_EXPORT void projectm_touch(projectm_handle instance, float x, float y,
int pressure, projectm_touch_type touch_type);
/**
* @brief Centers any waveforms under the coordinates to simulate dragging.
* @param instance The projectM instance handle.
* @param x The x coordinate of the drag.
* @param y the y coordinate of the drag.
* @param pressure The amount of pressure applied in a range from 0.0 to 1.0.
*/
PROJECTM_EXPORT void projectm_touch_drag(projectm_handle instance, float x, float y, int pressure);
/**
* @brief Removes any additional touch waveforms under the given coordinates.
* @param instance The projectM instance handle.
* @param x The last known x touch coordinate.
* @param y The last known y touch coordinate.
*/
PROJECTM_EXPORT void projectm_touch_destroy(projectm_handle instance, float x, float y);
/**
* @brief Removes all touch waveforms from the screen.
*
* Preset-defined waveforms will still be displayed.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_touch_destroy_all(projectm_handle instance);
/**
* @brief Sets the help menu text.
*
* The help menu will be toggled if the key mapped to PROJECTM_K_F1 is pressed.
*
* @param instance The projectM instance handle.
* @param help_text The help text to be displayed.
*/
PROJECTM_EXPORT void projectm_set_help_text(projectm_handle instance, const char* help_text);
/**
* @brief Displays a short message in the center of the rendering area for a few seconds.
*
* <p>Useful to display song titles and changed audio settings. Used internally by projectM to display setting
* changes like preset lock.</p>
*
* <p>Only one toast message is shown at a time. If this method is called while another message is shown, it
* will be replaced immediately.</p>
*
* @param instance The projectM instance handle.
* @param toast_message The message to display.
*/
PROJECTM_EXPORT void projectm_set_toast_message(projectm_handle instance, const char* toast_message);
/**
* @brief Returns a structure with the current projectM settings.
* @param instance The projectM instance handle.
* @return A struct with all currently used settings.
*/
PROJECTM_EXPORT projectm_settings_t* projectm_get_settings(projectm_handle instance);
/**
* @brief Saves the given settings struct into a file.
*
* The file can be loaded during projectM initialization. This is useful if the application needs to
* keep settings separate from the global system/user configuration.
*
* @param config_file The filename to store the settings in.
* @param settings The settings struct to store.
*/
PROJECTM_EXPORT void projectm_write_config(const char* config_file, const projectm_settings_t* settings);
/**
* @brief Selects a preset, but does not display it.
* @param instance The projectM instance handle.
* @param index The preset index to select.
*/
PROJECTM_EXPORT void projectm_select_preset_position(projectm_handle instance, unsigned int index);
/**
* @brief Selects and displays the preset.
* @param instance The projectM instance handle.
* @param index the preset to display.
* @param hard_cut If true, a hard cut is made, otherwise it will be blended smoothly.
*/
PROJECTM_EXPORT void projectm_select_preset(projectm_handle instance, unsigned int index, bool hard_cut);
/**
* @brief Populates the on-screen preset menu.
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_populate_preset_menu(projectm_handle instance);
/**
* @brief Removes a preset from the playlist.
* @param instance The projectM instance handle.
* @param index The preset index to remove from the playlist.
*/
PROJECTM_EXPORT void projectm_remove_preset(projectm_handle instance, unsigned int index);
/**
* @brief Clears the preset playlist.
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_clear_playlist(projectm_handle instance);
/**
* @brief Locks or unlocks the current preset.
*
* Locking effectively disables automatic preset transitions, both hard and soft cuts. Programmatic
* preset switches will still be executed.
*
* @param instance The projectM instance handle.
* @param lock True to lock the current preset, false to enable automatic transitions.
*/
PROJECTM_EXPORT void projectm_lock_preset(projectm_handle instance, bool lock);
/**
* @brief Returns whether the search text input mode is active or not.
* @param instance The projectM instance handle.
* @param no_minimum_length If set to true, will return true if at least one character has been typed, otherwise
* a minimum length of three characters is required.
* @return True if text input mode is active, false otherwise.
*/
PROJECTM_EXPORT bool projectm_is_text_input_active(projectm_handle instance, bool no_minimum_length);
/**
* @brief Returns the playlist index for the given preset name.
*
* If the preset name is found multiple times, the first matching index will be returned.
*
* @param instance The projectM instance handle.
* @param preset_name The preset name to search for.
* @return The first found playlist index of the requested preset, or 0 if the preset wasn't found.
*/
PROJECTM_EXPORT unsigned int projectm_get_preset_index(projectm_handle instance, const char* preset_name);
/**
* @brief Displays the preset with the given name.
* @param instance The projectM instance handle.
* @param preset_name The preset name to search for.
* @param hard_cut If true, the preset will be shown immediately, if false a soft transition will be rendered.
*/
PROJECTM_EXPORT void projectm_select_preset_by_name(projectm_handle instance, const char* preset_name, bool hard_cut);
/**
* @brief Sets the current preset search text.
* @param instance The projectM instance handle.
* @param search_text The search text used to search for presets in the current playlist.
*/
PROJECTM_EXPORT void projectm_set_search_text(projectm_handle instance, const char* search_text);
/**
* @brief Deletes one character from the preset search text.
*
* This is equivalent to pressing DEL in a text box.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_delete_search_text(projectm_handle instance);
/**
* @brief Deletes the whole search text.
*
* This will effectively leave preset search mode.
*
* @param instance The projectM instance handle.
*/
PROJECTM_EXPORT void projectm_reset_search_text(projectm_handle instance);
/**
* @brief Returns the currently selected preset index.
* @param instance The projectM instance handle.
* @param index A valid pointer to an unsigned int that will receive the preset index.
* @return True if a preset idnex was returned, false if no preset was selected, e.g. the playlist is empty.
*/
PROJECTM_EXPORT bool projectm_selected_preset_index(projectm_handle instance, unsigned int* index);
/**
* @brief Adds a new preset at the end of the playlist.
*
* The rating list is one rating per value of the projectm_preset_rating_type enumeration, with each actual enum
* value used as the index. If the rating list has the wrong length, the preset will not be added.
*
* @param instance The projectM instance handle.
* @param preset_url The full path and filename of the preset.
* @param preset_name The display name of the preset.
* @param rating_list A list with ratings for the preset, one rating per rating type.
* @param rating_list_length Length of the preset rating list.
*/
PROJECTM_EXPORT void projectm_add_preset_url(projectm_handle instance, const char* preset_url,
const char* preset_name, int* rating_list,
unsigned int rating_list_length);
/**
* @brief Adds a new preset at the given position in the playlist.
*
* The rating list is one rating per value of the projectm_preset_rating_type enumeration, with each actual enum
* value used as the index. If the rating list has the wrong length, the preset will not be added.
*
* @param instance The projectM instance handle.
* @param index The playlist index to insert the preset at. Must be less than or equal to the length of
* the playlist.
* @param preset_url The full path and filename of the preset.
* @param preset_name The display name of the preset.
* @param rating_list A list with ratings for the preset, one rating per rating type.
* @param rating_list_length Length of the preset rating list.
*/
PROJECTM_EXPORT void projectm_insert_preset_url(projectm_handle instance, unsigned int index, const char* preset_url,
const char* preset_name, int* rating_list,
unsigned int rating_list_length);
/**
* @brief Returns whether the currently selected preset has a valid position in the playlist.
*
* This function is useful to check if the currently displayed preset is still inside the bounds of
* the current playlist, for example after the playlist was changed.
*
* @param instance The projectM instance handle.
* @return True if the position is valid, false if outside bounds.
*/
PROJECTM_EXPORT bool projectm_preset_position_valid(projectm_handle instance);
/**
* @brief Returns the path and filename of the preset at the requested playlist index.
* @note Make sure the index is inside the playlist bounds!
* @param instance The projectM instance handle.
* @param index The playlist index to return the filename for.
* @return The full path and filename of the preset at the given index.
*/
PROJECTM_EXPORT const char* projectm_get_preset_url(projectm_handle instance, unsigned int index);
/**
* @brief Returns the display name of the preset at the requested playlist index.
* @note Make sure the index is inside the playlist bounds!
* @param instance The projectM instance handle.
* @param index The playlist index to return the display name for.
* @return The display name of the preset at the given index.
*/
PROJECTM_EXPORT const char* projectm_get_preset_name(projectm_handle instance, unsigned int index);
/**
* @brief Changes the display name of the given preset in the playlist.
* @param instance The projectM instance handle.
* @param index the playlist item index to change.
* @param name The new display name.
*/
PROJECTM_EXPORT void projectm_change_preset_name(projectm_handle instance, unsigned int index, const char* name);
/**
* @brief Returns the rating for the given index and transition type.
* @param instance The projectM instance handle.
* @param index The playlist item to retrieve the rating from.
* @param rating_type The rating type to retrieve, either hard or soft cut.
* @return The rating value of the requested item and type.
*/
PROJECTM_EXPORT int projectm_get_preset_rating(projectm_handle instance, unsigned int index,
projectm_preset_rating_type rating_type);
/**
* @brief Changes the rating or a playlist item and type.
* @param instance The projectM instance handle.
* @param index the playlist item to change the rating of.
* @param rating The new rating value.
* @param rating_type The type of the rating, either hard or soft cut.
*/
PROJECTM_EXPORT void projectm_change_preset_rating(projectm_handle instance, unsigned int index, int rating,
projectm_preset_rating_type rating_type);
/**
* @brief Returns the number of presets in the current playlist.
* @param instance The projectM instance handle.
* @return The number of presets in the currently loaded playlist.
*/
PROJECTM_EXPORT unsigned int projectm_get_playlist_size(projectm_handle instance);
/**
* @brief Enables or disables preset playlist shuffling.
* @param instance The projectM instance handle.
* @param shuffle_enabled True to randomly select the next preset, false to skip to the next item in line.
*/
PROJECTM_EXPORT void projectm_set_shuffle_enabled(projectm_handle instance, bool shuffle_enabled);
/**
* @brief Returns whether playlist shuffling is currently enabled or not.
* @param instance The projectM instance handle.
* @return True if shuffle is enabled, false if not.
*/
PROJECTM_EXPORT bool projectm_is_shuffle_enabled(projectm_handle instance);
/**
* @brief Gets the index of the provided preset name in the current search result list.
* @param instance The projectM instance handle.
* @param name The name of the preset to return the index for.
* @return The search result list index of the given preset name.
*/
PROJECTM_EXPORT unsigned int projectm_get_search_index(projectm_handle instance, const char* name);
/**
* @brief Switches to the previous preset in the current playlist.
*
* This is unaffected by the shuffle mode and will always switch to the previous item.
*
* @param instance The projectM instance handle.
* @param hard_cut True to immediately perform to the previous preset, false to do a soft transition.
*/
PROJECTM_EXPORT void projectm_select_previous(projectm_handle instance, bool hard_cut);
/**
* @brief Switches to the next preset in the current playlist.
*
* This is unaffected by the shuffle mode and will always switch to the next item.
*
* @param instance The projectM instance handle.
* @param hard_cut True to immediately perform to the next preset, false to do a soft transition.
*/
PROJECTM_EXPORT void projectm_select_next(projectm_handle instance, bool hard_cut);
/**
* @brief Switches to a random preset in the current playlist.
*
* This is unaffected by the shuffle mode and will always switch to a random item.
*
* @param instance The projectM instance handle.
* @param hard_cut True to immediately perform to a random preset, false to do a soft transition.
*/
PROJECTM_EXPORT void projectm_select_random(projectm_handle instance, bool hard_cut);
/**
* @brief Returns the current viewport width in pixels.
* @param instance The projectM instance handle.
* @return The viewport width in pixels.
*/
PROJECTM_EXPORT int projectm_get_window_width(projectm_handle instance);
/**
* @brief Returns the current viewport height in pixels.
* @param instance The projectM instance handle.
* @return The viewport height in pixels.
*/
PROJECTM_EXPORT int projectm_get_window_height(projectm_handle instance);
/**
* @brief Returns whether the current preset was loaded successfully or not.
* @param instance The projectM instance handle.
* @return True if the preset was not loaded successfully, false if it is displayed correctly.
*/
PROJECTM_EXPORT bool projectm_get_error_loading_current_preset(projectm_handle instance);
/**
* @brief Adds 1-channel 32-bit floating-point audio samples.
*
* <p>This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data, duplicating the channel.</p>
*
* <p>If possible, always use projectm_pcm_add_float_2ch_data() for best performance and quality.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data An array of PCM samples.
* @param sample_count The number of audio samples in pcm_data.
*/
PROJECTM_EXPORT void projectm_pcm_add_float_1ch_data(projectm_handle instance, const float* pcm_data,
unsigned int sample_count);
/**
* @brief Adds 2-channel 32-bit floating-point audio samples.
*
* <p>This function is used to add new audio data to projectM's internal audio buffer.</p>
*
* <p>This function represents projectM's internal audio data format. If possible, always use this function for best
* performance and quality.</p>
*
* <p>Channel order in pcm_data is LRLRLR.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data An array of PCM samples, two floats per sample.
* @param sample_count The number of audio samples in pcm_data. Half the actual size of pcm_data.
*/
PROJECTM_EXPORT void projectm_pcm_add_float_2ch_data(projectm_handle instance, const float* pcm_data,
unsigned int sample_count);
/**
* @brief Adds 512 2-channel 16-bit integer audio samples.
*
* <p>This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data.</p>
*
* <p>If possible, always use projectm_pcm_add_float_2ch_data() for best performance and quality.</p>
*
* <p>Channel indices are 0 for the left channel and 1 for the right channel. Use the projectm_pcm_channel
* enum values instead of numerical indices for readability.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data The audio data.
*/
PROJECTM_EXPORT void projectm_pcm_add_16bit_2ch_512(projectm_handle instance, const short pcm_data[2][512]);
/**
* @brief Adds 2-channel 16-bit integer audio samples.</p>
*
* <p>This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data.</p>
*
* <p>If possible, always use projectm_pcm_add_float_2ch_data() for best performance and quality.</p>
*
* <p>Channel order in pcm_data is LRLRLR.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data The audio data.
*/
PROJECTM_EXPORT void projectm_pcm_add_16bit_2ch_data(projectm_handle instance, const short* pcm_data,
unsigned int sample_count);
/**
* @brief Adds 1024 2-channel 8-bit integer audio samples.
*
* <p>This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data.</p>
*
* <p>If possible, always use projectm_pcm_add_float_2ch_data() for best performance and quality.</p>
*
* <p>Channel indices are 0 for the left channel and 1 for the right channel. Use the projectm_pcm_channel
* enum values instead of numerical indices for readability.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data The audio data.
*/
PROJECTM_EXPORT void projectm_pcm_add_8bit_2ch_1024(projectm_handle instance, const unsigned char pcm_data[2][1024]);
/**
* @brief Adds 512 2-channel 8-bit integer audio samples.
*
* <p>This function is used to add new audio data to projectM's internal audio buffer. It is internally converted
* to 2-channel float data.</p>
*
* <p>If possible, always use projectm_pcm_add_float_2ch_data() for best performance and quality.</p>
*
* <p>Channel indices are 0 for the left channel and 1 for the right channel. Use the projectm_pcm_channel
* enum values instead of numerical indices for readability.</p>
*
* @param instance The projectM instance handle.
* @param pcm_data The audio data.
*/
PROJECTM_EXPORT void projectm_pcm_add_8bit_2ch_512(projectm_handle instance, const unsigned char pcm_data[2][512]);

View File

@ -166,6 +166,8 @@ public:
projectM(std::string config_file, int flags = FLAG_NONE);
projectM(Settings settings, int flags = FLAG_NONE);
virtual ~projectM();
void projectM_resetGL( int width, int height );
void projectM_resetTextures();
void projectM_setTitle( std::string title );
@ -177,8 +179,6 @@ public:
void key_handler( projectMEvent event,
projectMKeycode keycode, projectMModifier modifier );
virtual ~projectM();
void changeTextureSize(int size);
void changeHardcutDuration(int seconds);
void changeHardcutDuration(double seconds);
@ -235,7 +235,7 @@ public:
/// Returns true if the text based search menu is up.
bool isTextInputActive(bool nomin = false) const;
unsigned int getPresetIndex(std::string &url) const;
unsigned int getPresetIndex(const std::string& url) const;
/// Plays a preset immediately when given preset name
void selectPresetByName(std::string name, bool hardCut = true);
@ -317,7 +317,7 @@ public:
std::vector<int> presetFuture;
/// Get the preset index given a name
unsigned int getSearchIndex(std::string &name) const;
unsigned int getSearchIndex(const std::string& name) const;
void selectPrevious(const bool);
void selectNext(const bool);