Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
169
Src/external_dependencies/openmpt-trunk/libopenmpt/.clang-format
Normal file
169
Src/external_dependencies/openmpt-trunk/libopenmpt/.clang-format
Normal file
|
@ -0,0 +1,169 @@
|
|||
# clang-format 14
|
||||
|
||||
Language: Cpp
|
||||
Standard: c++20
|
||||
|
||||
AccessModifierOffset: -2 #?
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignArrayOfStructures: Left
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveBitFields: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: AlignAfterOperator
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AttributeMacros: []
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: false
|
||||
AfterControlStatement: MultiLine
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
#AfterObjCDeclaration
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: true
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: true
|
||||
#BreakAfterJavaFieldAnnotations
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '' #?
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 2 #?
|
||||
ContinuationIndentWidth: 2 #?
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
EmptyLineAfterAccessModifier: Leave
|
||||
EmptyLineBeforeAccessModifier: Leave
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros: []
|
||||
IfMacros: ['MPT_MAYBE_CONSTANT_IF']
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories: [] #?
|
||||
IncludeIsMainRegex: '' #?
|
||||
IncludeIsMainSourceRegex: '' #?
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: NoIndent
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
#IndentRequiresClause: true
|
||||
#BeforeHash
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: true
|
||||
InsertTrailingCommas: None
|
||||
#JavaImportGroups
|
||||
#JavaScriptQuotes
|
||||
#JavaScriptWrapImports
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: OuterScope
|
||||
MacroBlockBegin: '' #?
|
||||
MacroBlockEnd: '' #?
|
||||
MaxEmptyLinesToKeep: 3
|
||||
NamespaceIndentation: None
|
||||
NamespaceMacros: [] #?
|
||||
#ObjCBinPackProtocolList
|
||||
#ObjCBlockIndentWidth
|
||||
#ObjCBreakBeforeNestedBlockParam
|
||||
#ObjCSpaceAfterProperty
|
||||
#ObjCSpaceBeforeProtocolList
|
||||
PackConstructorInitializers: Never
|
||||
#PenaltyBreakAssignment
|
||||
#PenaltyBreakBeforeFirstCallParameter
|
||||
#PenaltyBreakComment
|
||||
#PenaltyBreakFirstLessLess
|
||||
#PenaltyBreakOpenParenthesis
|
||||
#PenaltyBreakString
|
||||
#PenaltyBreakTemplateDeclaration
|
||||
#PenaltyExcessCharacter
|
||||
#PenaltyIndentedWhitespace
|
||||
#PenaltyReturnTypeOnItsOwnLine
|
||||
PointerAlignment: Middle
|
||||
PPIndentWidth: -1
|
||||
#RawStringFormats
|
||||
QualifierAlignment: Leave
|
||||
#QualifierOrder: ['static', 'inline', 'constexpr', 'volatile', 'const', 'restrict', 'type']
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: false
|
||||
RemoveBracesLLVM: false
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: false
|
||||
#SortJavaStaticImport
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
#AfterRequiresInClause: false
|
||||
#AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: true
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: false
|
||||
StatementAttributeLikeMacros: []
|
||||
StatementMacros: [ 'MPT_WARNING', 'MPT_TEST_GROUP_INLINE_IDENTIFIER', 'MPT_TEST_GROUP_INLINE', 'MPT_TEST_GROUP_STATIC' ] #?
|
||||
TabWidth: 2
|
||||
TypenameMacros: [] #?
|
||||
UseCRLF: false
|
||||
UseTab: ForContinuationAndIndentation
|
||||
WhitespaceSensitiveMacros:
|
||||
- MPT_PP_STRINGIFY
|
2632
Src/external_dependencies/openmpt-trunk/libopenmpt/Doxyfile
Normal file
2632
Src/external_dependencies/openmpt-trunk/libopenmpt/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,408 @@
|
|||
/'
|
||||
' libopenmpt_ext.bi
|
||||
' -----------------
|
||||
' Purpose: libopenmpt public FreeBASIC interface for libopenmpt extensions
|
||||
' Notes : (currently none)
|
||||
' Authors: Johannes Schultz
|
||||
' OpenMPT Devs
|
||||
' The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
'/
|
||||
|
||||
#Pragma Once
|
||||
|
||||
#Include Once "libopenmpt.bi"
|
||||
|
||||
Extern "C"
|
||||
|
||||
'* \brief Opaque type representing a libopenmpt extension module
|
||||
Type openmpt_module_ext
|
||||
opaque As Any Ptr
|
||||
End Type
|
||||
|
||||
/'* \brief Construct an openmpt_module_ext
|
||||
|
||||
\param stream_callbacks Input stream callback operations.
|
||||
\param stream Input stream to load the module from.
|
||||
\param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. May be NULL.
|
||||
\param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
|
||||
\param errfunc Error function to define error behaviour. May be NULL.
|
||||
\param erruser Error function user context.
|
||||
\param errorcode Pointer to an integer where an error may get stored. May be NULL.
|
||||
\param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
\param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
\return A pointer to the constructed openmpt_module_ext, or NULL on failure.
|
||||
\remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
|
||||
\sa openmpt_stream_callbacks
|
||||
\since 0.3.0
|
||||
'/
|
||||
Declare Function openmpt_module_ext_create(ByVal stream_callbacks As openmpt_stream_callbacks, ByVal stream As Any Ptr, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module_ext Ptr
|
||||
|
||||
/'* \brief Construct an openmpt_module_ext
|
||||
|
||||
\param filedata Data to load the module from.
|
||||
\param filesize Amount of data available.
|
||||
\param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext.
|
||||
\param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
|
||||
\param errfunc Error function to define error behaviour. May be NULL.
|
||||
\param erruser Error function user context.
|
||||
\param errorcode Pointer to an integer where an error may get stored. May be NULL.
|
||||
\param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
\param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
\return A pointer to the constructed openmpt_module_ext, or NULL on failure.
|
||||
\remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
|
||||
\since 0.3.0
|
||||
'/
|
||||
Declare Function openmpt_module_ext_create_from_memory(ByVal filedata As Const Any Ptr, ByVal filesize As UInteger, ByVal logfunc As openmpt_log_func, ByVal loguser As Any Ptr, ByVal errfunc As openmpt_error_func, ByVal erruser As Any Ptr, ByVal Error As Long Ptr, ByVal error_message As Const ZString Ptr Ptr, ByVal ctls As Const openmpt_module_initial_ctl Ptr) As openmpt_module_ext Ptr
|
||||
|
||||
/'* \brief Unload a previously created openmpt_module_ext from memory.
|
||||
|
||||
\param mod_ext The module to unload.
|
||||
\since 0.3.0
|
||||
'/
|
||||
Declare Sub openmpt_module_ext_destroy(ByVal mod_ext As openmpt_module_ext Ptr)
|
||||
|
||||
/'* \brief Retrieve the openmpt_module handle from an openmpt_module_ext handle.
|
||||
|
||||
\param mod_ext The extension module handle to convert
|
||||
\return An equivalent openmpt_module handle to pass to standard libopenmpt functions
|
||||
\since 0.3.0
|
||||
'/
|
||||
Declare Function openmpt_module_ext_get_module(ByVal mod_ext As openmpt_module_ext Ptr) As openmpt_module Ptr
|
||||
|
||||
/'* Retrieve a libopenmpt extension.
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param interface_id The name of the extension interface to retrieve (e.g. LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS).
|
||||
\param interface Appropriate structure of interface function pointers which is to be filled by this function (e.g. a pointer to a openmpt_module_ext_interface_pattern_vis structure).
|
||||
\param interface_size Size of the interface's structure of function pointers (e.g. sizeof(openmpt_module_ext_interface_pattern_vis)).
|
||||
\return 1 on success, 0 if the interface was not found.
|
||||
\since 0.3.0
|
||||
'/
|
||||
Declare Function openmpt_module_ext_get_interface(ByVal mod_ext As openmpt_module_ext Ptr, ByVal interface_id As Const ZString Ptr, ByVal interface As Any Ptr, ByVal interface_size As UInteger) As Long
|
||||
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS "pattern_vis"
|
||||
|
||||
'* Pattern command type
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_UNKNOWN = 0
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GENERAL = 1
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GLOBAL = 2
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_VOLUME = 3
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PANNING = 4
|
||||
Const OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PITCH = 5
|
||||
|
||||
Type openmpt_module_ext_interface_pattern_vis
|
||||
/'* Get pattern command type for pattern highlighting
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param pattern The pattern whose data should be retrieved.
|
||||
\param row The row from which the data should be retrieved.
|
||||
\param channel The channel from which the data should be retrieved.
|
||||
\return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
|
||||
\sa get_pattern_row_channel_effect_type
|
||||
'/
|
||||
get_pattern_row_channel_volume_effect_type As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long) As Long
|
||||
|
||||
/'* Get pattern command type for pattern highlighting
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param pattern The pattern whose data should be retrieved.
|
||||
\param row The row from which the data should be retrieved.
|
||||
\param channel The channel from which the data should be retrieved.
|
||||
\return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
|
||||
\sa get_pattern_row_channel_volume_effect_type
|
||||
'/
|
||||
get_pattern_row_channel_effect_type As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal pattern As Long, ByVal row As Long, ByVal channel As Long) As Long
|
||||
End Type
|
||||
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE "interactive"
|
||||
|
||||
Type openmpt_module_ext_interface_interactive
|
||||
/'* Set the current ticks per row (speed)
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param speed The new tick count in range [1, 65535].
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the speed is outside the specified range.
|
||||
\return 1 on success, 0 on failure.
|
||||
\sa openmpt_module_get_current_speed
|
||||
'/
|
||||
set_current_speed As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal speed As Long) As Long
|
||||
|
||||
/'* Set the current module tempo
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module.
|
||||
\return 1 on success, 0 on failure.
|
||||
\remarks The tempo may be reset by pattern commands at any time. Use set_tempo_factor to apply a tempo factor that is independent of pattern commands.
|
||||
\sa openmpt_module_get_current_tempo
|
||||
'/
|
||||
set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Long) As Long
|
||||
|
||||
/'* Set the current module tempo factor without affecting playback pitch
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo.
|
||||
\return 1 on success, 0 on failure.
|
||||
\remarks Modifying the tempo without applying the same pitch factor using set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
\sa openmpt_module_ext_interface_interactive.get_tempo_factor
|
||||
'/
|
||||
set_tempo_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal factor As Double) As Long
|
||||
|
||||
/'* Gets the current module tempo factor
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\return The current tempo factor.
|
||||
\sa openmpt_module_ext_interface_interactive.set_tempo_factor
|
||||
'/
|
||||
get_tempo_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
|
||||
|
||||
/'* Set the current module pitch factor without affecting playback speed
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch.
|
||||
\return 1 on success, 0 on failure.
|
||||
\remarks Modifying the pitch without applying the the same tempo factor using set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
\remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `2.0 ^ ( n / 12.0 )`
|
||||
\sa openmpt_module_ext_interface_interactive.get_pitch_factor
|
||||
'/
|
||||
set_pitch_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal factor As Double) As Long
|
||||
|
||||
/'* Gets the current module pitch factor
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\return The current pitch factor.
|
||||
\sa openmpt_module_ext_interface_interactive.set_pitch_factor
|
||||
'/
|
||||
get_pitch_factor As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
|
||||
|
||||
/'* Set the current global volume
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param volume The new global volume in range [0.0, 1.0]
|
||||
\return 1 on success, 0 on failure.
|
||||
\remarks The global volume may be reset by pattern commands at any time. Use openmpt_module_set_render_param to apply a global overall volume factor that is independent of pattern commands.
|
||||
\sa openmpt_module_ext_interface_interactive.get_global_volume
|
||||
'/
|
||||
set_global_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal volume As Double) As Long
|
||||
|
||||
/'* Get the current global volume
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\return The current global volume in range [0.0, 1.0]
|
||||
\sa openmpt_module_ext_interface_interactive.set_global_volume
|
||||
'/
|
||||
get_global_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr) As Double
|
||||
|
||||
/'* Set the current channel volume for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose volume should be set, in range [0, openmpt_module_get_num_channels()[
|
||||
\param volume The new channel volume in range [0.0, 1.0]
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\remarks The channel volume may be reset by pattern commands at any time.
|
||||
\sa openmpt_module_ext_interface_interactive.get_channel_volume
|
||||
'/
|
||||
set_channel_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal volume As Double) As Long
|
||||
|
||||
/'* Get the current channel volume for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose volume should be retrieved, in range [0, openmpt_module_get_num_channels()[
|
||||
\return The current channel volume in range [0.0, 1.0]
|
||||
\sa openmpt_module_ext_interface_interactive.set_channel_volume
|
||||
'/
|
||||
get_channel_volume As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double
|
||||
|
||||
/'* Set the current mute status for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose mute status should be set, in range [0, openmpt_module_get_num_channels()[
|
||||
\param mute The new mute status. true is muted, false is unmuted.
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\sa openmpt_module_ext_interface_interactive.get_channel_mute_status
|
||||
'/
|
||||
set_channel_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal mute As Long) As Long
|
||||
|
||||
/'* Get the current mute status for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose mute status should be retrieved, in range [0, openmpt_module_get_num_channels()[
|
||||
\return The current channel mute status. true is muted, false is unmuted.
|
||||
\sa openmpt_module_ext_interface_interactive.set_channel_mute_status
|
||||
'/
|
||||
get_channel_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
|
||||
|
||||
/'* Set the current mute status for an instrument
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param instrument The instrument whose mute status should be set, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
\param mute The new mute status. true is muted, false is unmuted.
|
||||
\return 1 on success, 0 on failure (instrument out of range).
|
||||
\sa openmpt_module_ext_interface_interactive.get_instrument_mute_status
|
||||
'/
|
||||
set_instrument_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long, ByVal mute As Long) As Long
|
||||
|
||||
/'* Get the current mute status for an instrument
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param instrument The instrument whose mute status should be retrieved, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
\return The current instrument mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range.
|
||||
\sa openmpt_module_ext_interface_interactive.set_instrument_mute_status
|
||||
'/
|
||||
get_instrument_mute_status As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long) As Long
|
||||
|
||||
/'* Play a note using the specified instrument
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param instrument The instrument that should be played, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
\param note The note to play, in rage [0, 119]. 60 is the middle C.
|
||||
\param volume The volume at which the note should be triggered, in range [0.0, 1.0]
|
||||
\param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center.
|
||||
\return The channel on which the note is played. This can pe be passed to stop_note to stop the note. -1 means that no channel could be allocated and the note is not played.
|
||||
\sa openmpt_module_ext_interface_interactive.stop_note
|
||||
\sa openmpt_module_ext_interface_interactive2.note_off
|
||||
\sa openmpt_module_ext_interface_interactive2.note_fade
|
||||
'/
|
||||
play_note As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal instrument As Long, ByVal note As Long, ByVal volume As Double, ByVal panning As Double) As Long
|
||||
|
||||
/'* Stop the note playing on the specified channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel on which the note should be stopped. This is the value returned by a previous play_note call.
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\sa openmpt_module_ext_interface_interactive.play_note
|
||||
\sa openmpt_module_ext_interface_interactive.note_off
|
||||
\sa openmpt_module_ext_interface_interactive2.note_fade
|
||||
'/
|
||||
stop_note As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
|
||||
End Type
|
||||
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE2 "interactive2"
|
||||
|
||||
Type openmpt_module_ext_interface_interactive2
|
||||
|
||||
/'* Sends a key-off command for the note playing on the specified channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel on which the key-off event should be triggered. This is the value returned by a previous play_note call.
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\remarks This method releases envelopes and sample sustain loops. If the sample has no sustain loop, or if the module does not use instruments, it does nothing.
|
||||
\sa openmpt_module_ext_interface_interactive.play_note
|
||||
\sa openmpt_module_ext_interface_interactive.stop_note
|
||||
\sa note_fade
|
||||
'/
|
||||
note_off As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
|
||||
|
||||
/'* Sends a note fade command for the note playing on the specified channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel on which the note should be faded. This is the value returned by a previous play_note call.
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\remarks This method uses the instrument's fade-out value. If the module does not use instruments, or the instrument's fade-out value is 0, it does nothing.
|
||||
\sa openmpt_module_ext_interface_interactive.play_note
|
||||
\sa openmpt_module_ext_interface_interactive.stop_note
|
||||
\sa note_fade
|
||||
'/
|
||||
note_fade As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Long
|
||||
|
||||
/'* Set the current panning for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel that should be panned. This is the value returned by a previous play_note call.
|
||||
\param panning The panning position to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
\return 1 on success, 0 on failure (channel out of range).
|
||||
\remarks This command affects subsequent notes played on the same channel, and may itself be overridden by subsequent panning commands encountered in the module itself.
|
||||
\sa openmpt_module_ext_interface_interactive2.get_channel_panning
|
||||
'/
|
||||
set_channel_panning As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal panning As Double) As Long
|
||||
|
||||
/'* Get the current panning position for a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose panning should be retrieved. This is the value returned by a previous play_note call.
|
||||
\return The current channel panning, in range [-1.0, 1.0], 0.0 is center.
|
||||
\sa openmpt_module_ext_interface_interactive2.set_channel_panning
|
||||
'/
|
||||
get_channel_panning As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double
|
||||
|
||||
/'* Set the finetune for the currently playing note on a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose finetune will be changed, in range [0, openmpt::module::get_num_channels()[
|
||||
\param finetune The finetune to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
\remarks This command does not affect subsequent notes played on the same channel, but may itself be overridden by subsequent finetune commands encountered in the module itself.
|
||||
\sa openmpt_module_ext_interface_interactive2.get_note_finetune
|
||||
'/
|
||||
set_note_finetune As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long, ByVal finetune As Double) As Long
|
||||
|
||||
/'* Get the finetune for the currently playing note on a channel
|
||||
|
||||
\param mod_ext The module handle to work on.
|
||||
\param channel The channel whose finetune should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
\return The current channel finetune, in range [-1.0, 1.0], 0.0 is center.
|
||||
\remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\sa openmpt_module_ext_interface_interactive2.set_note_finetune
|
||||
'/
|
||||
get_note_finetune As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double
|
||||
End Type
|
||||
|
||||
End Extern
|
||||
|
||||
/'* \brief Construct an openmpt_module_ext
|
||||
|
||||
\param file The FreeBASIC file handle to load from.
|
||||
\param logfunc Logging function where warning and errors are written. May be NULL.
|
||||
\param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
|
||||
\param errfunc Error function to define error behaviour. May be NULL.
|
||||
\param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
|
||||
\param errorcode Pointer to an integer where an error may get stored. May be NULL.
|
||||
\param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
\param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
\return A pointer to the constructed openmpt_module, or NULL on failure.
|
||||
\remarks The file handle can be closed after an openmpt_module has been constructed successfully.
|
||||
\sa openmpt_module_ext_create
|
||||
'/
|
||||
Function openmpt_module_ext_create_from_fbhandle(_
|
||||
ByVal file As Integer,_
|
||||
ByVal logfunc As openmpt_log_func = 0,_
|
||||
ByVal loguser As Any Ptr = 0,_
|
||||
ByVal errfunc As openmpt_error_func = 0,_
|
||||
ByVal erruser As Any Ptr = 0,_
|
||||
ByVal errorcode As Long Ptr = 0,_
|
||||
ByVal error_message As Const ZString Ptr Ptr = 0,_
|
||||
ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module_ext Ptr
|
||||
Return openmpt_module_ext_create(openmpt_stream_get_file_callbacks(), Cast(FILE Ptr, FileAttr(file, fbFileAttrHandle)), logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
|
||||
End Function
|
||||
|
||||
/'* \brief Construct an openmpt_module_ext
|
||||
|
||||
\param filename The file to load from.
|
||||
\param logfunc Logging function where warning and errors are written. May be NULL.
|
||||
\param loguser Logging function user context. Used to pass any user-defined data associated with this module to the logging function.
|
||||
\param errfunc Error function to define error behaviour. May be NULL.
|
||||
\param erruser Error function user context. Used to pass any user-defined data associated with this module to the error function.
|
||||
\param errorcode Pointer to an integer where an error may get stored. May be NULL.
|
||||
\param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
\param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
\return A pointer to the constructed openmpt_module, or NULL on failure.
|
||||
\sa openmpt_module_ext_create
|
||||
'/
|
||||
Function openmpt_module_ext_create_from_filename(_
|
||||
ByRef filename As String,_
|
||||
ByVal logfunc As openmpt_log_func = 0,_
|
||||
ByVal loguser As Any Ptr = 0,_
|
||||
ByVal errfunc As openmpt_error_func = 0,_
|
||||
ByVal erruser As Any Ptr = 0,_
|
||||
ByVal errorcode As Long Ptr = 0,_
|
||||
ByVal error_message As Const ZString Ptr Ptr = 0,_
|
||||
ByVal ctls As Const openmpt_module_initial_ctl Ptr = 0) As openmpt_module_ext Ptr
|
||||
Var file = fopen(filename, "rb")
|
||||
Var retval = CPtr(openmpt_module Ptr, 0)
|
||||
If(file <> 0) Then
|
||||
retval = openmpt_module_ext_create(openmpt_stream_get_file_callbacks(), file, logfunc, loguser, errfunc, erruser, errorcode, error_message, ctls)
|
||||
fclose(file)
|
||||
EndIf
|
||||
Return retval
|
||||
End Function
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
in_openmpt
|
||||
==========
|
||||
|
||||
in_openmpt is a module file (https://en.wikipedia.org/wiki/Module_file) input
|
||||
plugin for Winamp >= 2.0 (or compatible players). in_openmpt is based on
|
||||
libopenmpt.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
"in_openmpt.dll" must be placed into the Winamp "Plugins" directory, and
|
||||
"openmpt-mpg123.dll" must be placed into the Winamp directory.
|
||||
|
||||
|
||||
See https://lib.openmpt.org/ for documentation, FAQ and other details.
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
xmp-openmpt
|
||||
===========
|
||||
|
||||
xmp-openmpt is a module file (https://en.wikipedia.org/wiki/Module_file) input
|
||||
plugin for XMPlay >= 3.8.0.0. xmp-openmpt is based on libopenmpt.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
"xmp-openmpt.dll" and "openmpt-mpg123.dll" must both be placed into the XMPlay
|
||||
plugins directory.
|
||||
|
||||
|
||||
See https://lib.openmpt.org/ for documentation, FAQ and other details.
|
1087
Src/external_dependencies/openmpt-trunk/libopenmpt/dox/changelog.md
Normal file
1087
Src/external_dependencies/openmpt-trunk/libopenmpt/dox/changelog.md
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,122 @@
|
|||
|
||||
Dependencies {#dependencies}
|
||||
============
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
### libopenmpt
|
||||
|
||||
* Supported compilers for building libopenmpt:
|
||||
* **Microsoft Visual Studio 2017** or higher, running on a amd64 build
|
||||
system (other target systems are supported)
|
||||
|
||||
Please note that we do not support building with a later Visual Studio
|
||||
installation with an earlier compiler version. This is because, while
|
||||
later Visual Studio versions allow installing earlier compilers to be
|
||||
available via the later version's environment, in this configuration,
|
||||
the earlier compiler will still use the later C and C++ runtime's
|
||||
headers and implementation, which significantly increases the matrix of
|
||||
possible configurations to test.
|
||||
|
||||
* **GCC 8.1** or higher
|
||||
* **Clang 7** or higher
|
||||
* **MinGW-W64 8.1** or higher (it is recommended to preferably use
|
||||
posix threading model as opposed to win32 threading model)
|
||||
* **emscripten 1.39.1** or higher
|
||||
* **DJGPP GCC 8.1** or higher
|
||||
* any other **C++17 compliant** compiler
|
||||
|
||||
libopenmpt makes the following assumptions about the C++ implementation
|
||||
used for building:
|
||||
* `std::numeric_limits<unsigned char>::digits == 8` (enforced by
|
||||
static_assert)
|
||||
* existence of `std::uintptr_t` (enforced by static_assert)
|
||||
* in C++20 mode, `std::endian::little != std::endian::big` (enforced
|
||||
by static_assert)
|
||||
* `wchar_t` encoding is either UTF-16 or UTF-32 (implicitly assumed)
|
||||
* representation of basic source character set is ASCII (implicitly
|
||||
assumed)
|
||||
* representation of basic source character set is identical in char
|
||||
and `wchar_t` (implicitly assumed)
|
||||
|
||||
libopenmpt does not rely on any specific implementation defined or
|
||||
undefined behaviour (if it does, that's a bug in libopenmpt). In
|
||||
particular:
|
||||
* `char` can be `signed` or `unsigned`
|
||||
* shifting signed values is implementation defined
|
||||
* `signed` integer overflow is undefined
|
||||
* `float` and `double` can be non-IEEE754
|
||||
|
||||
libopenmpt can optionally support certain incomplete C++
|
||||
implementations:
|
||||
* platforms without `wchar_t` support (like DJGPP)
|
||||
* platforms without working `std::random_device` (like Emscripten when
|
||||
running in `AudioWorkletProcessor` context)
|
||||
* platforms without working `std::high_resolution_clock` (like
|
||||
Emscripten when running in `AudioWorkletProcessor` context)
|
||||
|
||||
* Required compilers to use libopenmpt:
|
||||
* Any **C89** / **C99** / **C11** compatible compiler should work with
|
||||
the C API as long as a **C99** compatible **stdint.h** is available.
|
||||
* Any **C++17** compatible compiler should work with the C++ API.
|
||||
* **J2B** support requires an inflate (deflate decompression) implementation:
|
||||
* **zlib** (or **miniz** can be used internally)
|
||||
* **MO3** support requires:
|
||||
* **libmpg123 >= 1.14.0** (or **minimp3 by Lion (github.com/lieff)** can
|
||||
be used internally)
|
||||
* **libogg**, **libvorbis**, and **libvorbisfile** (or **stb_vorbis** can
|
||||
be used internally)
|
||||
* Building on Unix-like systems requires:
|
||||
* **GNU make**
|
||||
* **pkg-config**
|
||||
* The Autotools-based build system requires:
|
||||
* **pkg-config 0.24** or higher
|
||||
* **zlib**
|
||||
* **doxygen**
|
||||
|
||||
### openmpt123
|
||||
|
||||
* Live sound output requires one of:
|
||||
* **PulseAudio**
|
||||
* **SDL 2**
|
||||
* **PortAudio v19**
|
||||
* **Win32**
|
||||
* **liballegro 4.2** on DJGPP/DOS
|
||||
|
||||
|
||||
Optional dependencies
|
||||
---------------------
|
||||
|
||||
### libopenmpt
|
||||
|
||||
* **doxygen 1.8** or higher is required to build the documentation.
|
||||
|
||||
### openmpt123
|
||||
|
||||
* Rendering to PCM files can use:
|
||||
* **FLAC 1.2** or higher
|
||||
* **libsndfile**
|
||||
* **Win32** for WAVE
|
||||
* raw PCM has no external dependencies
|
||||
* **help2man** is required to build the documentation.
|
||||
|
||||
|
||||
Source packages
|
||||
---------------
|
||||
|
||||
Building the source packages additionally requires:
|
||||
* 7z (7-zip)
|
||||
* autoconf
|
||||
* autoconf-archive
|
||||
* automake
|
||||
* awk (mawk)
|
||||
* git
|
||||
* gzip
|
||||
* help2man
|
||||
* libtool
|
||||
* subversion
|
||||
* tar
|
||||
* xpath (libxml-xpath-perl)
|
||||
* zip
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
Getting Started {#gettingstarted}
|
||||
===============
|
||||
|
||||
|
||||
How to compile
|
||||
--------------
|
||||
|
||||
|
||||
### libopenmpt and openmpt123
|
||||
|
||||
- Autotools
|
||||
|
||||
Grab a `libopenmpt-VERSION-autotools.tar.gz` tarball.
|
||||
|
||||
./configure
|
||||
make
|
||||
make check
|
||||
sudo make install
|
||||
|
||||
Cross-compilation is generally supported (although only tested for
|
||||
targetting MinGW-w64).
|
||||
|
||||
Note that some MinGW-w64 distributions come with the `win32` threading model
|
||||
enabled by default instead of the `posix` threading model. The `win32`
|
||||
threading model lacks proper support for C++11 `<thread>` and `<mutex>` as
|
||||
well as thread-safe magic statics. It is recommended to use the `posix`
|
||||
threading model for libopenmpt for this reason. On Debian, the appropriate
|
||||
configure command is
|
||||
`./configure --host=x86_64-w64-mingw32 CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix`
|
||||
for 64bit, or
|
||||
`./configure --host=i686-w64-mingw32 CC=i686-w64-mingw32-gcc-posix CXX=i686-w64-mingw32-g++-posix`
|
||||
for 32bit. Other MinGW-w64 distributions may differ.
|
||||
|
||||
- Visual Studio:
|
||||
|
||||
- You will find solutions for Visual Studio in the matching
|
||||
`build/vsVERSIONwinWINDOWSVERSION/` folder.
|
||||
Minimal projects that target Windows 10 UWP are available in
|
||||
`build/vsVERSIONuwp/`.
|
||||
Most projects are supported with any of the mentioned Visual Studio
|
||||
verions, with the following exceptions:
|
||||
|
||||
- in_openmpt: Requires Visual Studio with MFC.
|
||||
|
||||
- xmp-openmpt: Requires Visual Studio with MFC.
|
||||
|
||||
- libopenmpt requires the compile host system to be amd64 or ARM64 when
|
||||
building with Visual Studio.
|
||||
|
||||
- In order to build libopenmpt for Windows XP, the Visual Studio 2017 XP
|
||||
targetting toolset as well as the Windows 8.1 SDK need to be installed.
|
||||
The SDK is optionally included with Visual Studio 2017, but must be
|
||||
separately installed with later Visual Studio versions.
|
||||
|
||||
The Windows 8.1 SDK is available from
|
||||
<https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/>
|
||||
or directly from
|
||||
<https://download.microsoft.com/download/B/0/C/B0C80BA3-8AD6-4958-810B-6882485230B5/standalonesdk/sdksetup.exe>
|
||||
.
|
||||
|
||||
- You will need the Winamp 5 SDK and the XMPlay SDK if you want to
|
||||
compile the plugins for these 2 players. They can be downloaded
|
||||
automatically on Windows 7 or later by just running the
|
||||
`build/download_externals.cmd` script.
|
||||
|
||||
If you do not want to or cannot use this script, you may follow these
|
||||
manual steps instead:
|
||||
|
||||
- Winamp 5 SDK:
|
||||
|
||||
To build libopenmpt as a winamp input plugin, copy the contents of
|
||||
`WA5.55_SDK.exe` to include/winamp/.
|
||||
|
||||
Please visit
|
||||
[winamp.com](http://wiki.winamp.com/wiki/Plug-in_Developer) to
|
||||
download the SDK.
|
||||
You can disable in_openmpt in the solution configuration.
|
||||
|
||||
- XMPlay SDK:
|
||||
|
||||
To build libopenmpt with XMPlay input plugin support, copy the
|
||||
contents of xmp-sdk.zip into include/xmplay/.
|
||||
|
||||
Please visit [un4seen.com](https://www.un4seen.com/xmplay.html) to
|
||||
download the SDK.
|
||||
You can disable xmp-openmpt in the solution configuration.
|
||||
|
||||
- Makefile
|
||||
|
||||
The makefile supports different build environments and targets via the
|
||||
`CONFIG=` parameter directly to the make invocation.
|
||||
Use `make CONFIG=$newconfig clean` when switching between different configs
|
||||
because the makefile cleans only intermediates and target that are active
|
||||
for the current config and no configuration state is kept around across
|
||||
invocations.
|
||||
|
||||
- native build:
|
||||
|
||||
Simply run
|
||||
|
||||
make
|
||||
|
||||
which will try to guess the compiler based on your operating system.
|
||||
|
||||
- gcc or clang (on Unix-like systems, including Mac OS X with MacPorts,
|
||||
and Haiku (32-bit Hybrid and 64-bit)):
|
||||
|
||||
The Makefile requires pkg-config for native builds.
|
||||
For sound output in openmpt123, PortAudio or SDL is required.
|
||||
openmpt123 can optionally use libflac and libsndfile to render PCM
|
||||
files to disk.
|
||||
|
||||
When you want to use gcc, run:
|
||||
|
||||
make CONFIG=gcc
|
||||
|
||||
When you want to use clang, it is recommended to do:
|
||||
|
||||
make CONFIG=clang
|
||||
|
||||
- mingw-w64:
|
||||
|
||||
make CONFIG=mingw64-win32 # for win32
|
||||
|
||||
make CONFIG=mingw64-win64 # for win64
|
||||
|
||||
- emscripten (on Unix-like systems):
|
||||
|
||||
Run:
|
||||
|
||||
# generates WebAssembly with JavaScript fallback
|
||||
make CONFIG=emscripten EMSCRIPTEN_TARGET=all
|
||||
|
||||
or
|
||||
|
||||
# generates WebAssembly
|
||||
make CONFIG=emscripten EMSCRIPTEN_TARGET=wasm
|
||||
|
||||
or
|
||||
|
||||
# generates JavaScript with compatibility for older VMs
|
||||
make CONFIG=emscripten EMSCRIPTEN_TARGET=js
|
||||
|
||||
Running the test suite on the command line is also supported by using
|
||||
node.js. Depending on how your distribution calls the `node.js` binary,
|
||||
you might have to edit `build/make/config-emscripten.mk`.
|
||||
|
||||
- DJGPP / DOS
|
||||
|
||||
Cross-compilation from Linux systems is supported with DJGPP GCC via
|
||||
|
||||
make CONFIG=djgpp
|
||||
|
||||
`openmpt123` can use liballegro 4.2 for sound output on DJGPP/DOS.
|
||||
liballegro can either be installed system-wide in the DJGPP environment
|
||||
or downloaded into the `libopenmpt` source tree.
|
||||
|
||||
make CONFIG=djgpp USE_ALLEGRO42=1 # use installed liballegro
|
||||
|
||||
or
|
||||
|
||||
./build/download_externals.sh # download liballegro source
|
||||
make CONFIG=djgpp USE_ALLEGRO42=1 BUNDLED_ALLEGRO42=1
|
||||
|
||||
- American Fuzzy Lop:
|
||||
|
||||
To compile libopenmpt with fuzzing instrumentation for afl-fuzz, run:
|
||||
|
||||
make CONFIG=afl
|
||||
|
||||
For more detailed instructions, read `contrib/fuzzing/readme.md`.
|
||||
|
||||
- other compilers:
|
||||
|
||||
To compile libopenmpt with other compliant compilers, run:
|
||||
|
||||
make CONFIG=generic
|
||||
|
||||
|
||||
The `Makefile` supports some customizations. You might want to read the top
|
||||
which should get you some possible make settings, like e.g.
|
||||
`make DYNLINK=0` or similar. Cross compiling or different compiler would
|
||||
best be implemented via new `config-*.mk` files.
|
||||
|
||||
The `Makefile` also supports building doxygen documentation by using
|
||||
|
||||
make doc
|
||||
|
||||
Binaries and documentation can be installed systen-wide with
|
||||
|
||||
make PREFIX=/yourprefix install
|
||||
make PREFIX=/yourprefix install-doc
|
||||
|
||||
Some systems (i.e. Linux) require running
|
||||
|
||||
sudo ldconfig
|
||||
|
||||
in order for the system linker to be able to pick up newly installed
|
||||
libraries.
|
||||
|
||||
`PREFIX` defaults to `/usr/local`. A `DESTDIR=` parameter is also
|
||||
supported.
|
||||
|
||||
- Android NDK
|
||||
|
||||
See `build/android_ndk/README.AndroidNDK.txt`.
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
/*!
|
||||
* \mainpage Contents
|
||||
*
|
||||
* libopenmpt is a cross-platform C++ and C library to decode <a href="https://en.wikipedia.org/wiki/Module_file">tracked music files (modules)</a> into a raw PCM audio stream.
|
||||
*
|
||||
* libopenmpt is based on the player code of the Open ModPlug Tracker project (OpenMPT, <a href="https://openmpt.org/">https://openmpt.org/</a>)
|
||||
*
|
||||
* \section toc Contents
|
||||
* - \ref md_README "README"
|
||||
* - \ref dependencies "Dependencies"
|
||||
* - \ref gettingstarted "Getting Started"
|
||||
* - \ref packaging "Packaging"
|
||||
* - \ref md_doc_contributing "Contributing"
|
||||
* - \ref md_doc_libopenmpt_styleguide "libopenmpt Style Guide"
|
||||
* - \ref md_doc_openmpt_styleguide "OpenMPT Style Guide"
|
||||
* - \ref tests "Tests"
|
||||
* - \ref changelog "Changelog"
|
||||
* - \ref md_doc_module_formats "Implementing new Module Formats"
|
||||
* - <a href="https://bugs.openmpt.org/">Issue Tracker</a>
|
||||
* \subsection toc_apis APIs
|
||||
* - libopenmpt
|
||||
* - \ref libopenmpt "Common Details"
|
||||
* - libopenmpt C++
|
||||
* - \ref libopenmpt_cpp_overview "Overview"
|
||||
* - \ref libopenmpt_cpp "Details"
|
||||
* - libopenmpt C
|
||||
* - \ref libopenmpt_c_overview "Overview"
|
||||
* - \ref libopenmpt_c "Details"
|
||||
* - libopenmpt_ext C++
|
||||
* - \ref libopenmpt_ext_cpp_overview "Overview"
|
||||
* - \ref libopenmpt_ext_cpp "Details"
|
||||
* - libopenmpt_ext C
|
||||
* - \ref libopenmpt_ext_c_overview "Overview"
|
||||
* - \ref libopenmpt_ext_c "Details"
|
||||
*
|
||||
* \section toc_website Website
|
||||
* https://lib.openmpt.org/
|
||||
*
|
||||
* \section toc_license License
|
||||
* \include LICENSE
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,38 @@
|
|||
Packaging {#packaging}
|
||||
=========
|
||||
|
||||
|
||||
Packaging
|
||||
---------
|
||||
|
||||
|
||||
### Packaging recommendations for distribution package maintainers
|
||||
|
||||
* libopenmpt (since 0.3) uses SemVer 2.0.0 versioning. See
|
||||
[semver.org](https://semver.org/spec/v2.0.0.html). Clause 4 is ignored for
|
||||
libopenmpt, which means that libopenmpt will also provide API/ABI
|
||||
compatibility semantics for pre-1.0.0 versions as required by SemVer 2.0.0
|
||||
only for post-1.0.0 versions. The SemVer versioning scheme is incompatible
|
||||
with Debian/Ubuntu package versions, however it can easily be processed to
|
||||
be compatible by replacing '-' (hyphen) with '~' (tilde). It is recommended
|
||||
that you use this exact transformation if required.
|
||||
* Use the autotools source package.
|
||||
* Use the default set of dependencies required by the autotools package.
|
||||
* Read \ref libopenmpt_c_staticlinking and thus possibly pass
|
||||
`CXXSTDLIB_PCLIBSPRIVATE` variable to `configure` if appropriate and/or
|
||||
desired.
|
||||
* Run the test suite in your build process.
|
||||
* Send any build system improvement patches upstream.
|
||||
* Do not include the libmodplug emulation layer in the default libopenmpt
|
||||
binary package. Either do not package it at all, or provide a separate
|
||||
package named libopenmpt-modplug or libmodplug-openmpt (or similar), which
|
||||
depends on libopenmpt, provides libmodplug, and conflicts with original
|
||||
libmodplug.
|
||||
* Split openmpt123 into its own binary package because it has more
|
||||
dependencies than libopenmpt itself.
|
||||
* Consider providing an additional openmpt123 package (in addition to the
|
||||
default openmpt123 package with all audio output drivers), built with fewer
|
||||
audio output drivers so it does not transitively depend on X11. Name that
|
||||
package and its executable openmpt123-nox (or whatever else may be common
|
||||
practice in your distribution).
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
Tests {#tests}
|
||||
=====
|
||||
|
||||
|
||||
libopenmpt provides some basic unit tests that check the platform for general
|
||||
sanity and do some basic internal functionality testing. The test suite
|
||||
requires a special libopenmpt build that includes file saving functionality
|
||||
which is not included in normal builds. This is handled by all provided build
|
||||
systems automatically.
|
||||
|
||||
### Running Tests
|
||||
|
||||
#### On Unix-like systems
|
||||
|
||||
Compile with
|
||||
|
||||
make $YOURMAKEOPTIONS clean
|
||||
make $YOURMAKEOPTIONS
|
||||
|
||||
and run
|
||||
|
||||
make $YOURMAKEOPTIONS check
|
||||
|
||||
As the build system retains no state between make invocations, you have to
|
||||
provide your make options on every make invocation.
|
||||
|
||||
#### Autotools-based build system
|
||||
|
||||
./configure
|
||||
make check
|
||||
|
||||
#### On Windows
|
||||
|
||||
Using Visual Studio 20??, compile
|
||||
|
||||
build\vs20??\libopenmpt_test.sln
|
||||
|
||||
and run
|
||||
|
||||
bin\$ARCH\libopenmpt_test.exe
|
||||
|
||||
from the root of the source tree.
|
||||
|
|
@ -0,0 +1,587 @@
|
|||
/*
|
||||
* in_openmpt.cpp
|
||||
* --------------
|
||||
* Purpose: libopenmpt winamp input plugin implementation
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef NO_WINAMP
|
||||
|
||||
#if defined(_MFC_VER) || 1
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#if !defined(WINVER) && !defined(_WIN32_WINDOWS)
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MPT_BUILD_RETRO)
|
||||
#if defined(_MSC_VER)
|
||||
#define MPT_WITH_MFC
|
||||
#endif
|
||||
#else
|
||||
#if defined(_WIN32_WINNT)
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
#if defined(_MSC_VER)
|
||||
#define MPT_WITH_MFC
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MPT_WITH_MFC)
|
||||
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // Avoid binary bloat from linking unused MFC controls
|
||||
#endif // MPT_WITH_MFC
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#if defined(MPT_WITH_MFC)
|
||||
#include <afxwin.h>
|
||||
#include <afxcmn.h>
|
||||
#endif // MPT_WITH_MFC
|
||||
#include <windows.h>
|
||||
#endif // _MFC_VER
|
||||
|
||||
#ifdef LIBOPENMPT_BUILD_DLL
|
||||
#undef LIBOPENMPT_BUILD_DLL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
#include "libopenmpt.hpp"
|
||||
|
||||
#include "libopenmpt_plugin_settings.hpp"
|
||||
|
||||
#include "libopenmpt_plugin_gui.hpp"
|
||||
|
||||
#include "svn_version.h"
|
||||
#if defined(OPENMPT_VERSION_REVISION)
|
||||
static const char * in_openmpt_string = "in_openmpt " OPENMPT_API_VERSION_STRING "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_VERSION_REVISION);
|
||||
#else
|
||||
static const char * in_openmpt_string = "in_openmpt " OPENMPT_API_VERSION_STRING;
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef UNICODE
|
||||
#define UNICODE_INPUT_PLUGIN
|
||||
#endif
|
||||
#ifndef _MSC_VER
|
||||
#define _MSC_VER 1300
|
||||
#endif
|
||||
#include "winamp/Winamp/IN2.H"
|
||||
#include "winamp/Winamp/wa_ipc.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#define BPS 16
|
||||
|
||||
#define WINAMP_DSP_HEADROOM_FACTOR 2
|
||||
#define WINAMP_BUFFER_SIZE_FRAMES 576
|
||||
|
||||
#define WM_OPENMPT_SEEK (WM_USER+3)
|
||||
|
||||
#define SHORT_TITLE "in_openmpt"
|
||||
|
||||
static void apply_options();
|
||||
|
||||
static std::string StringEncode( const std::wstring &src, UINT codepage )
|
||||
{
|
||||
int required_size = WideCharToMultiByte( codepage, 0, src.c_str(), -1, NULL, 0, NULL, NULL );
|
||||
if(required_size <= 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
std::vector<CHAR> encoded_string( required_size );
|
||||
WideCharToMultiByte( codepage, 0, src.c_str(), -1, &encoded_string[0], encoded_string.size(), NULL, NULL );
|
||||
return &encoded_string[0];
|
||||
}
|
||||
|
||||
static std::wstring StringDecode( const std::string & src, UINT codepage )
|
||||
{
|
||||
int required_size = MultiByteToWideChar( codepage, 0, src.c_str(), -1, NULL, 0 );
|
||||
if(required_size <= 0)
|
||||
{
|
||||
return std::wstring();
|
||||
}
|
||||
std::vector<WCHAR> decoded_string( required_size );
|
||||
MultiByteToWideChar( codepage, 0, src.c_str(), -1, &decoded_string[0], decoded_string.size() );
|
||||
return &decoded_string[0];
|
||||
}
|
||||
|
||||
#if defined(UNICODE)
|
||||
|
||||
static std::wstring StringToWINAPI( const std::wstring & src )
|
||||
{
|
||||
return src;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static std::string StringToWINAPI( const std::wstring & src )
|
||||
{
|
||||
return StringEncode( src, CP_ACP );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Tstring, typename Tstring2, typename Tstring3>
|
||||
static inline Tstring StringReplace( Tstring str, const Tstring2 & oldStr_, const Tstring3 & newStr_ ) {
|
||||
std::size_t pos = 0;
|
||||
const Tstring oldStr = oldStr_;
|
||||
const Tstring newStr = newStr_;
|
||||
while ( ( pos = str.find( oldStr, pos ) ) != Tstring::npos ) {
|
||||
str.replace( pos, oldStr.length(), newStr );
|
||||
pos += newStr.length();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
struct self_winamp_t {
|
||||
std::vector<char> filetypes_string;
|
||||
libopenmpt::plugin::settings settings;
|
||||
int samplerate;
|
||||
int channels;
|
||||
std::basic_string<TCHAR> cached_filename;
|
||||
std::basic_string<TCHAR> cached_title;
|
||||
int cached_length;
|
||||
std::basic_string<TCHAR> cached_infotext;
|
||||
std::int64_t decode_position_frames;
|
||||
openmpt::module * mod;
|
||||
HANDLE PlayThread;
|
||||
DWORD PlayThreadID;
|
||||
bool paused;
|
||||
std::vector<std::int16_t> buffer;
|
||||
std::vector<std::int16_t> interleaved_buffer;
|
||||
self_winamp_t() : settings(TEXT(SHORT_TITLE), true) {
|
||||
filetypes_string.clear();
|
||||
settings.changed = apply_options;
|
||||
settings.load();
|
||||
std::vector<std::string> extensions = openmpt::get_supported_extensions();
|
||||
for ( std::vector<std::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext ) {
|
||||
std::copy( (*ext).begin(), (*ext).end(), std::back_inserter( filetypes_string ) );
|
||||
filetypes_string.push_back('\0');
|
||||
std::copy( SHORT_TITLE, SHORT_TITLE + std::strlen(SHORT_TITLE), std::back_inserter( filetypes_string ) );
|
||||
filetypes_string.push_back('\0');
|
||||
}
|
||||
filetypes_string.push_back('\0');
|
||||
samplerate = settings.samplerate;
|
||||
channels = settings.channels;
|
||||
cached_filename = std::basic_string<TCHAR>();
|
||||
cached_title = std::basic_string<TCHAR>();
|
||||
cached_length = 0;
|
||||
cached_infotext = std::basic_string<TCHAR>();
|
||||
decode_position_frames = 0;
|
||||
mod = 0;
|
||||
PlayThread = 0;
|
||||
PlayThreadID = 0;
|
||||
paused = false;
|
||||
buffer.resize( WINAMP_BUFFER_SIZE_FRAMES * channels );
|
||||
interleaved_buffer.resize( WINAMP_BUFFER_SIZE_FRAMES * channels * WINAMP_DSP_HEADROOM_FACTOR );
|
||||
}
|
||||
~self_winamp_t() {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
static self_winamp_t * self = 0;
|
||||
|
||||
static void apply_options() {
|
||||
if ( self->mod ) {
|
||||
self->mod->set_repeat_count( self->settings.repeatcount );
|
||||
self->mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, self->settings.mastergain_millibel );
|
||||
self->mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, self->settings.stereoseparation );
|
||||
self->mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, self->settings.interpolationfilterlength );
|
||||
self->mod->set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, self->settings.ramping );
|
||||
self->mod->ctl_set_boolean( "render.resampler.emulate_amiga", self->settings.use_amiga_resampler ? true : false );
|
||||
switch ( self->settings.amiga_filter_type ) {
|
||||
case 0:
|
||||
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "auto" );
|
||||
break;
|
||||
case 1:
|
||||
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "unfiltered" );
|
||||
break;
|
||||
case 0xA500:
|
||||
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "a500" );
|
||||
break;
|
||||
case 0xA1200:
|
||||
self->mod->ctl_set_text( "render.resampler.emulate_amiga_type", "a1200" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
self->settings.save();
|
||||
}
|
||||
|
||||
extern In_Module inmod;
|
||||
|
||||
static DWORD WINAPI DecodeThread( LPVOID );
|
||||
|
||||
static std::basic_string<TCHAR> generate_infotext( const std::basic_string<TCHAR> & filename, const openmpt::module & mod ) {
|
||||
std::basic_ostringstream<TCHAR> str;
|
||||
str << TEXT("filename: ") << filename << std::endl;
|
||||
str << TEXT("duration: ") << mod.get_duration_seconds() << TEXT("seconds") << std::endl;
|
||||
std::vector<std::string> metadatakeys = mod.get_metadata_keys();
|
||||
for ( std::vector<std::string>::iterator key = metadatakeys.begin(); key != metadatakeys.end(); ++key ) {
|
||||
if ( *key == "message_raw" ) {
|
||||
continue;
|
||||
}
|
||||
str << StringToWINAPI( StringDecode( *key, CP_UTF8 ) ) << TEXT(": ") << StringToWINAPI( StringDecode( mod.get_metadata(*key), CP_UTF8 ) ) << std::endl;
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static void config( HWND hwndParent ) {
|
||||
#if 1
|
||||
libopenmpt::plugin::gui_edit_settings( &self->settings, hwndParent, TEXT(SHORT_TITLE) );
|
||||
#else
|
||||
static_cast<void>(hwndParent);
|
||||
#endif
|
||||
apply_options();
|
||||
}
|
||||
|
||||
static void about( HWND hwndParent ) {
|
||||
std::ostringstream about;
|
||||
about << SHORT_TITLE << " version " << openmpt::string::get( "library_version" ) << " " << "(built " << openmpt::string::get( "build" ) << ")" << std::endl;
|
||||
about << " Copyright (c) 2013-2022 OpenMPT Project Developers and Contributors (https://lib.openmpt.org/)" << std::endl;
|
||||
about << " OpenMPT version " << openmpt::string::get( "core_version" ) << std::endl;
|
||||
about << std::endl;
|
||||
about << openmpt::string::get( "contact" ) << std::endl;
|
||||
about << std::endl;
|
||||
about << "Show full credits?" << std::endl;
|
||||
if ( MessageBox( hwndParent, StringToWINAPI( StringDecode( about.str(), CP_UTF8 ) ).c_str(), TEXT(SHORT_TITLE), MB_ICONINFORMATION | MB_YESNOCANCEL | MB_DEFBUTTON1 ) != IDYES ) {
|
||||
return;
|
||||
}
|
||||
std::ostringstream credits;
|
||||
credits << openmpt::string::get( "credits" );
|
||||
#if 1
|
||||
libopenmpt::plugin::gui_show_file_info( hwndParent, TEXT(SHORT_TITLE), StringToWINAPI( StringReplace( StringDecode( credits.str(), CP_UTF8 ), L"\n", L"\r\n" ) ) );
|
||||
#else
|
||||
MessageBox( hwndParent, StringToWINAPI( StringReplace(StringDecode(credits.str(), CP_UTF8 ), L"\n", L"\r\n" ) ).c_str(), TEXT(SHORT_TITLE), MB_OK );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void init() {
|
||||
if ( !self ) {
|
||||
self = new self_winamp_t();
|
||||
inmod.FileExtensions = &(self->filetypes_string[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void quit() {
|
||||
if ( self ) {
|
||||
inmod.FileExtensions = NULL;
|
||||
delete self;
|
||||
self = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int isourfile( const in_char * /* fn */ ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int play( const in_char * fn ) {
|
||||
if ( !fn ) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
std::ifstream s( fn, std::ios::binary );
|
||||
std::map< std::string, std::string > ctls;
|
||||
ctls["seek.sync_samples"] = "1";
|
||||
self->mod = new openmpt::module( s, std::clog, ctls );
|
||||
self->cached_filename = fn;
|
||||
self->cached_title = StringToWINAPI( StringDecode( self->mod->get_metadata( "title" ), CP_UTF8 ) );
|
||||
self->cached_length = static_cast<int>( self->mod->get_duration_seconds() * 1000.0 );
|
||||
self->cached_infotext = generate_infotext( self->cached_filename, *self->mod );
|
||||
apply_options();
|
||||
self->samplerate = self->settings.samplerate;
|
||||
self->channels = self->settings.channels;
|
||||
int maxlatency = inmod.outMod->Open( self->samplerate, self->channels, BPS, -1, -1 );
|
||||
std::ostringstream str;
|
||||
str << maxlatency;
|
||||
inmod.SetInfo( self->mod->get_num_channels(), self->samplerate/1000, self->channels, 1 );
|
||||
inmod.SAVSAInit( maxlatency, self->samplerate );
|
||||
inmod.VSASetInfo( self->channels, self->samplerate );
|
||||
inmod.outMod->SetVolume( -666 );
|
||||
inmod.outMod->SetPan( 0 );
|
||||
self->paused = false;
|
||||
self->decode_position_frames = 0;
|
||||
self->PlayThread = CreateThread( NULL, 0, DecodeThread, NULL, 0, &self->PlayThreadID );
|
||||
return 0;
|
||||
} catch ( ... ) {
|
||||
if ( self->mod ) {
|
||||
delete self->mod;
|
||||
self->mod = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void pause() {
|
||||
self->paused = true;
|
||||
inmod.outMod->Pause( 1 );
|
||||
}
|
||||
|
||||
static void unpause() {
|
||||
self->paused = false;
|
||||
inmod.outMod->Pause( 0 );
|
||||
}
|
||||
|
||||
static int ispaused() {
|
||||
return self->paused ? 1 : 0;
|
||||
}
|
||||
|
||||
static void stop() {
|
||||
PostThreadMessage( self->PlayThreadID, WM_QUIT, 0, 0 );
|
||||
WaitForSingleObject( self->PlayThread, INFINITE );
|
||||
CloseHandle( self->PlayThread );
|
||||
self->PlayThread = 0;
|
||||
self->PlayThreadID = 0;
|
||||
delete self->mod;
|
||||
self->mod = 0;
|
||||
inmod.outMod->Close();
|
||||
inmod.SAVSADeInit();
|
||||
}
|
||||
|
||||
static int getlength() {
|
||||
return self->cached_length;
|
||||
}
|
||||
|
||||
static int getoutputtime() {
|
||||
//return (int)( self->decode_position_frames * 1000 / self->mod->get_render_param( openmpt::module::RENDER_SAMPLERATE_HZ ) /* + ( inmod.outMod->GetOutputTime() - inmod.outMod->GetWrittenTime() ) */ );
|
||||
return inmod.outMod->GetOutputTime();
|
||||
}
|
||||
|
||||
static void setoutputtime( int time_in_ms ) {
|
||||
PostThreadMessage( self->PlayThreadID, WM_OPENMPT_SEEK, 0, time_in_ms );
|
||||
}
|
||||
|
||||
static void setvolume( int volume ) {
|
||||
inmod.outMod->SetVolume( volume );
|
||||
}
|
||||
|
||||
static void setpan( int pan ) {
|
||||
inmod.outMod->SetPan( pan );
|
||||
}
|
||||
|
||||
static int infobox( const in_char * fn, HWND hWndParent ) {
|
||||
if ( fn && fn[0] != '\0' && self->cached_filename != std::basic_string<TCHAR>(fn) ) {
|
||||
try {
|
||||
std::ifstream s( fn, std::ios::binary );
|
||||
openmpt::module mod( s );
|
||||
#if 1
|
||||
libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( generate_infotext( fn, mod ), TEXT("\n"), TEXT("\r\n") ) );
|
||||
#else
|
||||
MessageBox( hWndParent, StringReplace( generate_infotext( fn, mod ), TEXT("\n"), TEXT("\r\n") ).c_str(), TEXT(SHORT_TITLE), MB_OK );
|
||||
#endif
|
||||
} catch ( ... ) {
|
||||
}
|
||||
} else {
|
||||
#if 1
|
||||
libopenmpt::plugin::gui_show_file_info( hWndParent, TEXT(SHORT_TITLE), StringReplace( self->cached_infotext, TEXT("\n"), TEXT("\r\n") ) );
|
||||
#else
|
||||
MessageBox( hWndParent, StringReplace( self->cached_infotext, TEXT("\n"), TEXT("\r\n") ).c_str(), TEXT(SHORT_TITLE), MB_OK );
|
||||
#endif
|
||||
}
|
||||
return INFOBOX_UNCHANGED;
|
||||
}
|
||||
|
||||
|
||||
static void getfileinfo( const in_char * filename, in_char * title, int * length_in_ms ) {
|
||||
if ( !filename || *filename == '\0' ) {
|
||||
if ( length_in_ms ) {
|
||||
*length_in_ms = self->cached_length;
|
||||
}
|
||||
if ( title ) {
|
||||
std::basic_string<TCHAR> truncated_title = self->cached_title;
|
||||
if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
|
||||
truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
|
||||
}
|
||||
_tcscpy( title, truncated_title.c_str() );
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
std::ifstream s( filename, std::ios::binary );
|
||||
openmpt::module mod( s );
|
||||
if ( length_in_ms ) {
|
||||
*length_in_ms = static_cast<int>( mod.get_duration_seconds() * 1000.0 );
|
||||
}
|
||||
if ( title ) {
|
||||
std::basic_string<TCHAR> truncated_title = StringToWINAPI( StringDecode( mod.get_metadata("title"), CP_UTF8 ) );
|
||||
if ( truncated_title.length() >= GETFILEINFO_TITLE_LENGTH ) {
|
||||
truncated_title.resize( GETFILEINFO_TITLE_LENGTH - 1 );
|
||||
}
|
||||
_tcscpy( title, truncated_title.c_str() );
|
||||
}
|
||||
} catch ( ... ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eq_set( int /* on */ , char /* data */ [10], int /* preamp */ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
static DWORD WINAPI DecodeThread( LPVOID ) {
|
||||
MSG msg;
|
||||
PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE );
|
||||
bool eof = false;
|
||||
while ( true ) {
|
||||
bool quit = false;
|
||||
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
|
||||
if ( msg.message == WM_QUIT ) {
|
||||
quit = true;
|
||||
} else if ( msg.message == WM_OPENMPT_SEEK ) {
|
||||
double pos_seconds = self->mod->set_position_seconds( msg.lParam * 0.001 );
|
||||
self->decode_position_frames = (std::int64_t)( pos_seconds * (double)self->samplerate);
|
||||
eof = false;
|
||||
inmod.outMod->Flush( (int)( pos_seconds * 1000.0 ) );
|
||||
}
|
||||
}
|
||||
if ( quit ) {
|
||||
break;
|
||||
}
|
||||
if ( eof ) {
|
||||
inmod.outMod->CanWrite(); // update output plugin state
|
||||
if ( !inmod.outMod->IsPlaying() ) {
|
||||
PostMessage( inmod.hMainWindow, WM_WA_MPEG_EOF, 0, 0 );
|
||||
return 0;
|
||||
}
|
||||
Sleep( 10 );
|
||||
} else {
|
||||
bool dsp_active = inmod.dsp_isactive() ? true : false;
|
||||
if ( inmod.outMod->CanWrite() >= (int)( WINAMP_BUFFER_SIZE_FRAMES * self->channels * sizeof( signed short ) ) * ( dsp_active ? WINAMP_DSP_HEADROOM_FACTOR : 1 ) ) {
|
||||
int frames = 0;
|
||||
switch ( self->channels ) {
|
||||
case 1:
|
||||
frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES );
|
||||
for ( int frame = 0; frame < frames; frame++ ) {
|
||||
self->interleaved_buffer[frame*1+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES );
|
||||
for ( int frame = 0; frame < frames; frame++ ) {
|
||||
self->interleaved_buffer[frame*2+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
self->interleaved_buffer[frame*2+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+2*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+3*WINAMP_BUFFER_SIZE_FRAMES );
|
||||
for ( int frame = 0; frame < frames; frame++ ) {
|
||||
self->interleaved_buffer[frame*4+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
self->interleaved_buffer[frame*4+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
self->interleaved_buffer[frame*4+2] = self->buffer[2*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
self->interleaved_buffer[frame*4+3] = self->buffer[3*WINAMP_BUFFER_SIZE_FRAMES+frame];
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( frames == 0 ) {
|
||||
eof = true;
|
||||
} else {
|
||||
self->decode_position_frames += frames;
|
||||
std::int64_t decode_pos_ms = (self->decode_position_frames * 1000 / self->samplerate );
|
||||
inmod.SAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
|
||||
inmod.VSAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
|
||||
if ( dsp_active ) {
|
||||
frames = inmod.dsp_dosamples( &( self->interleaved_buffer[0] ), frames, BPS, self->channels, self->samplerate );
|
||||
}
|
||||
int bytes = frames * self->channels * sizeof( signed short );
|
||||
inmod.outMod->Write( (char*)&( self->interleaved_buffer[0] ), bytes );
|
||||
}
|
||||
} else {
|
||||
Sleep( 10 );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
extern In_Module inmod;
|
||||
#endif
|
||||
In_Module inmod = {
|
||||
IN_VER,
|
||||
const_cast< char * >( in_openmpt_string ), // SHORT_TITLE,
|
||||
0, // hMainWindow
|
||||
0, // hDllInstance
|
||||
NULL, // filled later in Init() "mptm\0ModPlug Tracker Module (*.mptm)\0",
|
||||
1, // is_seekable
|
||||
1, // uses output
|
||||
config,
|
||||
about,
|
||||
init,
|
||||
quit,
|
||||
getfileinfo,
|
||||
infobox,
|
||||
isourfile,
|
||||
play,
|
||||
pause,
|
||||
unpause,
|
||||
ispaused,
|
||||
stop,
|
||||
getlength,
|
||||
getoutputtime,
|
||||
setoutputtime,
|
||||
setvolume,
|
||||
setpan,
|
||||
0,0,0,0,0,0,0,0,0, // vis
|
||||
0,0, // dsp
|
||||
eq_set,
|
||||
NULL, // setinfo
|
||||
0 // out_mod
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) In_Module * winampGetInModule2();
|
||||
extern "C" __declspec(dllexport) In_Module * winampGetInModule2() {
|
||||
return &inmod;
|
||||
}
|
||||
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
|
||||
#ifdef _MFC_VER
|
||||
|
||||
namespace libopenmpt {
|
||||
namespace plugin {
|
||||
|
||||
void DllMainAttach() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
void DllMainDetach() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace libopenmpt
|
||||
|
||||
#else
|
||||
|
||||
// nothing
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
|
||||
#endif // NO_WINAMP
|
1552
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt.h
Normal file
1552
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt.h
Normal file
File diff suppressed because it is too large
Load diff
1185
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt.hpp
Normal file
1185
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt.hpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,14 @@
|
|||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
includedir=@includedir@
|
||||
libdir=@libdir@
|
||||
|
||||
Name: libopenmpt
|
||||
Description: Tracker module player based on OpenMPT
|
||||
Version: @VERSION@
|
||||
Requires.private: @LIBOPENMPT_REQUIRES_PRIVATE@
|
||||
Libs: -L${libdir} -lopenmpt
|
||||
Libs.private: @LIBOPENMPT_LIBS_PRIVATE@
|
||||
Cflags: -I${includedir}
|
||||
|
1881
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt_c.cpp
Normal file
1881
Src/external_dependencies/openmpt-trunk/libopenmpt/libopenmpt_c.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* libopenmpt_config.h
|
||||
* -------------------
|
||||
* Purpose: libopenmpt public interface configuration
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_CONFIG_H
|
||||
#define LIBOPENMPT_CONFIG_H
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
/*! \defgroup libopenmpt libopenmpt */
|
||||
|
||||
/*! \addtogroup libopenmpt
|
||||
@{
|
||||
*/
|
||||
|
||||
/* provoke warnings if already defined */
|
||||
#define LIBOPENMPT_API
|
||||
#undef LIBOPENMPT_API
|
||||
#define LIBOPENMPT_CXX_API
|
||||
#undef LIBOPENMPT_CXX_API
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
/*! \addtogroup libopenmpt_c
|
||||
@{
|
||||
*/
|
||||
|
||||
/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_buffer.h exists. */
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_BUFFER
|
||||
|
||||
/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_fd.h exists.
|
||||
* \since 0.3
|
||||
* \remarks
|
||||
* Use the following to check for availability:
|
||||
* \code
|
||||
* #include <libopenmpt/libopenmpt.h>
|
||||
* #if defined(LIBOPENMPT_STREAM_CALLBACKS_FD) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1)))
|
||||
* #include <libopenmpt/libopenmpt_stream_callbacks_fd.h>
|
||||
* #endif
|
||||
* \endcode
|
||||
*/
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_FD
|
||||
|
||||
/*! \brief Defined if libopenmpt/libopenmpt_stream_callbacks_file.h exists.
|
||||
* \since 0.3
|
||||
* \remarks
|
||||
* Use the following to check for availability:
|
||||
* \code
|
||||
* #include <libopenmpt/libopenmpt.h>
|
||||
* #if defined(LIBOPENMPT_STREAM_CALLBACKS_FILE) || ((OPENMPT_API_VERSION_MAJOR == 0) && ((OPENMPT_API_VERSION_MINOR == 2) || (OPENMPT_API_VERSION_MINOR == 1)))
|
||||
* #include <libopenmpt/libopenmpt_stream_callbacks_file.h>
|
||||
* #endif
|
||||
* \endcode
|
||||
*/
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_FILE
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
/*! \addtogroup libopenmpt
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined(__DOXYGEN__)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport)
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport)
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL
|
||||
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default"))) __attribute__((used))
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default"))) __attribute__((used))
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default"))) __attribute__((used))
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden")))
|
||||
|
||||
#elif (defined(__GNUC__) || defined(__clang__)) && defined(_WIN32)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport)
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport)
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default")))
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden")))
|
||||
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT __attribute__((visibility("default")))
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT __attribute__((visibility("default")))
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC __attribute__((visibility("default")))
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL __attribute__((visibility("hidden")))
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT __declspec(dllexport)
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT __declspec(dllimport)
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL
|
||||
|
||||
#else
|
||||
|
||||
#define LIBOPENMPT_API_HELPER_EXPORT
|
||||
#define LIBOPENMPT_API_HELPER_IMPORT
|
||||
#define LIBOPENMPT_API_HELPER_PUBLIC
|
||||
#define LIBOPENMPT_API_HELPER_LOCAL
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LIBOPENMPT_BUILD_DLL)
|
||||
#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_EXPORT
|
||||
#elif defined(LIBOPENMPT_USE_DLL)
|
||||
#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_IMPORT
|
||||
#else
|
||||
#define LIBOPENMPT_API LIBOPENMPT_API_HELPER_PUBLIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#define LIBOPENMPT_CXX_API LIBOPENMPT_API
|
||||
|
||||
#if defined(LIBOPENMPT_USE_DLL)
|
||||
#if defined(_MSC_VER) && !defined(_DLL)
|
||||
#error "C++ interface is disabled if libopenmpt is built as a DLL and the runtime is statically linked. This is not supported by microsoft and cannot possibly work. Ever."
|
||||
#undef LIBOPENMPT_CXX_API
|
||||
#define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
/* Only the C API is supported for emscripten. Disable the C++ API. */
|
||||
#undef LIBOPENMPT_CXX_API
|
||||
#define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
/* C */
|
||||
|
||||
#if !defined(LIBOPENMPT_NO_DEPRECATE)
|
||||
#if defined(__clang__)
|
||||
#define LIBOPENMPT_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(__GNUC__)
|
||||
#define LIBOPENMPT_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define LIBOPENMPT_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define LIBOPENMPT_DEPRECATED
|
||||
#endif
|
||||
#else
|
||||
#define LIBOPENMPT_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if !defined(LIBOPENMPT_NO_DEPRECATE)
|
||||
LIBOPENMPT_DEPRECATED static const int LIBOPENMPT_DEPRECATED_STRING_CONSTANT = 0;
|
||||
#define LIBOPENMPT_DEPRECATED_STRING( str ) ( LIBOPENMPT_DEPRECATED_STRING_CONSTANT ? ( str ) : ( str ) )
|
||||
#else
|
||||
#define LIBOPENMPT_DEPRECATED_STRING( str ) str
|
||||
#endif
|
||||
#else
|
||||
#define LIBOPENMPT_DEPRECATED_STRING( str ) str
|
||||
#endif
|
||||
|
||||
|
||||
/* C++ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#if defined(LIBOPENMPT_ASSUME_CPLUSPLUS)
|
||||
#endif
|
||||
|
||||
#if !defined(LIBOPENMPT_NO_DEPRECATE)
|
||||
#define LIBOPENMPT_ATTR_DEPRECATED [[deprecated]]
|
||||
#else
|
||||
#define LIBOPENMPT_ATTR_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#include "libopenmpt_version.h"
|
||||
|
||||
#endif /* LIBOPENMPT_CONFIG_H */
|
|
@ -0,0 +1,500 @@
|
|||
/*
|
||||
* libopenmpt_cxx.cpp
|
||||
* ------------------
|
||||
* Purpose: libopenmpt C++ interface implementation
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
#include "libopenmpt_internal.h"
|
||||
#include "libopenmpt.hpp"
|
||||
#include "libopenmpt_ext.hpp"
|
||||
|
||||
#include "libopenmpt_impl.hpp"
|
||||
#include "libopenmpt_ext_impl.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
exception::exception( const std::string & text_ ) noexcept
|
||||
: std::exception()
|
||||
, text(0)
|
||||
{
|
||||
text = static_cast<char*>( std::malloc( text_.length() + 1 ) );
|
||||
if ( text ) {
|
||||
std::memcpy( text, text_.c_str(), text_.length() + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
exception::exception( const exception & other ) noexcept
|
||||
: std::exception()
|
||||
, text(0)
|
||||
{
|
||||
const char * const text_ = ( other.what() ? other.what() : "" );
|
||||
text = static_cast<char*>( std::malloc( std::strlen( text_ ) + 1 ) );
|
||||
if ( text ) {
|
||||
std::memcpy( text, text_, std::strlen( text_ ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
exception::exception( exception && other ) noexcept
|
||||
: std::exception()
|
||||
, text(0)
|
||||
{
|
||||
text = std::move( other.text );
|
||||
other.text = 0;
|
||||
}
|
||||
|
||||
exception & exception::operator = ( const exception & other ) noexcept {
|
||||
if ( this == &other ) {
|
||||
return *this;
|
||||
}
|
||||
if ( text ) {
|
||||
std::free( text );
|
||||
text = 0;
|
||||
}
|
||||
const char * const text_ = ( other.what() ? other.what() : "" );
|
||||
text = static_cast<char*>( std::malloc( std::strlen( text_ ) + 1 ) );
|
||||
if ( text ) {
|
||||
std::memcpy( text, text_, std::strlen( text_ ) + 1 );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
exception & exception::operator = ( exception && other ) noexcept {
|
||||
if ( this == &other ) {
|
||||
return *this;
|
||||
}
|
||||
if ( text ) {
|
||||
std::free( text );
|
||||
text = 0;
|
||||
}
|
||||
text = std::move( other.text );
|
||||
other.text = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
exception::~exception() noexcept {
|
||||
if ( text ) {
|
||||
std::free( text );
|
||||
text = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char * exception::what() const noexcept {
|
||||
if ( text ) {
|
||||
return text;
|
||||
} else {
|
||||
return "out of memory";
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t get_library_version() {
|
||||
return openmpt::version::get_library_version();
|
||||
}
|
||||
|
||||
std::uint32_t get_core_version() {
|
||||
return openmpt::version::get_core_version();
|
||||
}
|
||||
|
||||
namespace string {
|
||||
|
||||
std::string get( const std::string & key ) {
|
||||
return openmpt::version::get_string( key );
|
||||
}
|
||||
|
||||
} // namespace string
|
||||
|
||||
} // namespace openmpt
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
std::vector<std::string> get_supported_extensions() {
|
||||
return openmpt::module_impl::get_supported_extensions();
|
||||
}
|
||||
|
||||
bool is_extension_supported( const std::string & extension ) {
|
||||
return openmpt::module_impl::is_extension_supported( extension );
|
||||
}
|
||||
bool is_extension_supported2( std::string_view extension ) {
|
||||
return openmpt::module_impl::is_extension_supported( extension );
|
||||
}
|
||||
|
||||
double could_open_probability( std::istream & stream, double effort, std::ostream & log ) {
|
||||
return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique<std_ostream_log>( log ) );
|
||||
}
|
||||
double could_open_propability( std::istream & stream, double effort, std::ostream & log ) {
|
||||
return openmpt::module_impl::could_open_probability( stream, effort, openmpt::helper::make_unique<std_ostream_log>( log ) );
|
||||
}
|
||||
|
||||
std::size_t probe_file_header_get_recommended_size() {
|
||||
return openmpt::module_impl::probe_file_header_get_recommended_size();
|
||||
}
|
||||
int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size, std::uint64_t filesize ) {
|
||||
return openmpt::module_impl::probe_file_header( flags, data, size, filesize );
|
||||
}
|
||||
int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize ) {
|
||||
return openmpt::module_impl::probe_file_header( flags, data, size, filesize );
|
||||
}
|
||||
int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size ) {
|
||||
return openmpt::module_impl::probe_file_header( flags, data, size );
|
||||
}
|
||||
int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size ) {
|
||||
return openmpt::module_impl::probe_file_header( flags, data, size );
|
||||
}
|
||||
int probe_file_header( std::uint64_t flags, std::istream & stream ) {
|
||||
return openmpt::module_impl::probe_file_header( flags, stream );
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4702) // unreachable code
|
||||
#endif // _MSC_VER
|
||||
|
||||
module::module( const module & ) : impl(nullptr) {
|
||||
throw exception("openmpt::module is non-copyable");
|
||||
}
|
||||
|
||||
// cppcheck-suppress operatorEqVarError
|
||||
void module::operator = ( const module & ) {
|
||||
throw exception("openmpt::module is non-copyable");
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
|
||||
module::module() : impl(0) {
|
||||
return;
|
||||
}
|
||||
|
||||
void module::set_impl( module_impl * i ) {
|
||||
impl = i;
|
||||
}
|
||||
|
||||
module::module( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( stream, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::vector<std::byte> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::byte * beg, const std::byte * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::byte * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::vector<std::uint8_t> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::uint8_t * beg, const std::uint8_t * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::uint8_t * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const std::vector<char> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const char * beg, const char * end, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( beg, end - beg, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::module( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : impl(0) {
|
||||
impl = new module_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
}
|
||||
|
||||
module::~module() {
|
||||
delete impl;
|
||||
impl = 0;
|
||||
}
|
||||
|
||||
void module::select_subsong( std::int32_t subsong ) {
|
||||
impl->select_subsong( subsong );
|
||||
}
|
||||
std::int32_t module::get_selected_subsong() const {
|
||||
return impl->get_selected_subsong();
|
||||
}
|
||||
|
||||
void module::set_repeat_count( std::int32_t repeat_count ) {
|
||||
impl->set_repeat_count( repeat_count );
|
||||
}
|
||||
std::int32_t module::get_repeat_count() const {
|
||||
return impl->get_repeat_count();
|
||||
}
|
||||
|
||||
double module::get_duration_seconds() const {
|
||||
return impl->get_duration_seconds();
|
||||
}
|
||||
|
||||
double module::set_position_seconds( double seconds ) {
|
||||
return impl->set_position_seconds( seconds );
|
||||
}
|
||||
double module::get_position_seconds() const {
|
||||
return impl->get_position_seconds();
|
||||
}
|
||||
|
||||
double module::set_position_order_row( std::int32_t order, std::int32_t row ) {
|
||||
return impl->set_position_order_row( order, row );
|
||||
}
|
||||
|
||||
std::int32_t module::get_render_param( int param ) const {
|
||||
return impl->get_render_param( param );
|
||||
}
|
||||
void module::set_render_param( int param, std::int32_t value ) {
|
||||
impl->set_render_param( param, value );
|
||||
}
|
||||
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * mono ) {
|
||||
return impl->read( samplerate, count, mono );
|
||||
}
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right ) {
|
||||
return impl->read( samplerate, count, left, right );
|
||||
}
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right ) {
|
||||
return impl->read( samplerate, count, left, right, rear_left, rear_right );
|
||||
}
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, float * mono ) {
|
||||
return impl->read( samplerate, count, mono );
|
||||
}
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right ) {
|
||||
return impl->read( samplerate, count, left, right );
|
||||
}
|
||||
std::size_t module::read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right ) {
|
||||
return impl->read( samplerate, count, left, right, rear_left, rear_right );
|
||||
}
|
||||
std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo ) {
|
||||
return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo );
|
||||
}
|
||||
std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad ) {
|
||||
return impl->read_interleaved_quad( samplerate, count, interleaved_quad );
|
||||
}
|
||||
std::size_t module::read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo ) {
|
||||
return impl->read_interleaved_stereo( samplerate, count, interleaved_stereo );
|
||||
}
|
||||
std::size_t module::read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad ) {
|
||||
return impl->read_interleaved_quad( samplerate, count, interleaved_quad );
|
||||
}
|
||||
|
||||
std::vector<std::string> module::get_metadata_keys() const {
|
||||
return impl->get_metadata_keys();
|
||||
}
|
||||
std::string module::get_metadata( const std::string & key ) const {
|
||||
return impl->get_metadata( key );
|
||||
}
|
||||
|
||||
double module::get_current_estimated_bpm() const {
|
||||
return impl->get_current_estimated_bpm();
|
||||
}
|
||||
std::int32_t module::get_current_speed() const {
|
||||
return impl->get_current_speed();
|
||||
}
|
||||
std::int32_t module::get_current_tempo() const {
|
||||
return impl->get_current_tempo();
|
||||
}
|
||||
std::int32_t module::get_current_order() const {
|
||||
return impl->get_current_order();
|
||||
}
|
||||
std::int32_t module::get_current_pattern() const {
|
||||
return impl->get_current_pattern();
|
||||
}
|
||||
std::int32_t module::get_current_row() const {
|
||||
return impl->get_current_row();
|
||||
}
|
||||
std::int32_t module::get_current_playing_channels() const {
|
||||
return impl->get_current_playing_channels();
|
||||
}
|
||||
|
||||
float module::get_current_channel_vu_mono( std::int32_t channel ) const {
|
||||
return impl->get_current_channel_vu_mono( channel );
|
||||
}
|
||||
float module::get_current_channel_vu_left( std::int32_t channel ) const {
|
||||
return impl->get_current_channel_vu_left( channel );
|
||||
}
|
||||
float module::get_current_channel_vu_right( std::int32_t channel ) const {
|
||||
return impl->get_current_channel_vu_right( channel );
|
||||
}
|
||||
float module::get_current_channel_vu_rear_left( std::int32_t channel ) const {
|
||||
return impl->get_current_channel_vu_rear_left( channel );
|
||||
}
|
||||
float module::get_current_channel_vu_rear_right( std::int32_t channel ) const {
|
||||
return impl->get_current_channel_vu_rear_right( channel );
|
||||
}
|
||||
|
||||
std::int32_t module::get_num_subsongs() const {
|
||||
return impl->get_num_subsongs();
|
||||
}
|
||||
std::int32_t module::get_num_channels() const {
|
||||
return impl->get_num_channels();
|
||||
}
|
||||
std::int32_t module::get_num_orders() const {
|
||||
return impl->get_num_orders();
|
||||
}
|
||||
std::int32_t module::get_num_patterns() const {
|
||||
return impl->get_num_patterns();
|
||||
}
|
||||
std::int32_t module::get_num_instruments() const {
|
||||
return impl->get_num_instruments();
|
||||
}
|
||||
std::int32_t module::get_num_samples() const {
|
||||
return impl->get_num_samples();
|
||||
}
|
||||
|
||||
std::vector<std::string> module::get_subsong_names() const {
|
||||
return impl->get_subsong_names();
|
||||
}
|
||||
std::vector<std::string> module::get_channel_names() const {
|
||||
return impl->get_channel_names();
|
||||
}
|
||||
std::vector<std::string> module::get_order_names() const {
|
||||
return impl->get_order_names();
|
||||
}
|
||||
std::vector<std::string> module::get_pattern_names() const {
|
||||
return impl->get_pattern_names();
|
||||
}
|
||||
std::vector<std::string> module::get_instrument_names() const {
|
||||
return impl->get_instrument_names();
|
||||
}
|
||||
std::vector<std::string> module::get_sample_names() const {
|
||||
return impl->get_sample_names();
|
||||
}
|
||||
|
||||
std::int32_t module::get_order_pattern( std::int32_t order ) const {
|
||||
return impl->get_order_pattern( order );
|
||||
}
|
||||
std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const {
|
||||
return impl->get_pattern_num_rows( pattern );
|
||||
}
|
||||
|
||||
std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
|
||||
return impl->get_pattern_row_channel_command( pattern, row, channel, command );
|
||||
}
|
||||
|
||||
std::string module::format_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
|
||||
return impl->format_pattern_row_channel_command( pattern, row, channel, command );
|
||||
}
|
||||
std::string module::highlight_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
|
||||
return impl->highlight_pattern_row_channel_command( pattern, row, channel, command );
|
||||
}
|
||||
|
||||
std::string module::format_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const {
|
||||
return impl->format_pattern_row_channel( pattern, row, channel, width, pad );
|
||||
}
|
||||
std::string module::highlight_pattern_row_channel( std::int32_t pattern, std::int32_t row, std::int32_t channel, std::size_t width, bool pad ) const {
|
||||
return impl->highlight_pattern_row_channel( pattern, row, channel, width, pad );
|
||||
}
|
||||
|
||||
std::vector<std::string> module::get_ctls() const {
|
||||
return impl->get_ctls();
|
||||
}
|
||||
|
||||
std::string module::ctl_get( const std::string & ctl ) const {
|
||||
return impl->ctl_get( ctl );
|
||||
}
|
||||
bool module::ctl_get_boolean( std::string_view ctl ) const {
|
||||
return impl->ctl_get_boolean( ctl );
|
||||
}
|
||||
std::int64_t module::ctl_get_integer( std::string_view ctl ) const {
|
||||
return impl->ctl_get_integer( ctl );
|
||||
}
|
||||
double module::ctl_get_floatingpoint( std::string_view ctl ) const {
|
||||
return impl->ctl_get_floatingpoint( ctl );
|
||||
}
|
||||
std::string module::ctl_get_text( std::string_view ctl ) const {
|
||||
return impl->ctl_get_text( ctl );
|
||||
}
|
||||
|
||||
void module::ctl_set( const std::string & ctl, const std::string & value ) {
|
||||
impl->ctl_set( ctl, value );
|
||||
}
|
||||
void module::ctl_set_boolean( std::string_view ctl, bool value ) {
|
||||
impl->ctl_set_boolean( ctl, value );
|
||||
}
|
||||
void module::ctl_set_integer( std::string_view ctl, std::int64_t value ) {
|
||||
impl->ctl_set_integer( ctl, value );
|
||||
}
|
||||
void module::ctl_set_floatingpoint( std::string_view ctl, double value ) {
|
||||
impl->ctl_set_floatingpoint( ctl, value );
|
||||
}
|
||||
void module::ctl_set_text( std::string_view ctl, std::string_view value ) {
|
||||
impl->ctl_set_text( ctl, value );
|
||||
}
|
||||
|
||||
module_ext::module_ext( std::istream & stream, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( stream, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const std::vector<std::uint8_t> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const std::vector<char> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const std::vector<std::byte> & data, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const std::uint8_t * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const char * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const std::byte * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::module_ext( const void * data, std::size_t size, std::ostream & log, const std::map< std::string, std::string > & ctls ) : ext_impl(0) {
|
||||
ext_impl = new module_ext_impl( data, size, openmpt::helper::make_unique<std_ostream_log>( log ), ctls );
|
||||
set_impl( ext_impl );
|
||||
}
|
||||
module_ext::~module_ext() {
|
||||
set_impl( 0 );
|
||||
delete ext_impl;
|
||||
ext_impl = 0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4702) // unreachable code
|
||||
#endif // _MSC_VER
|
||||
module_ext::module_ext( const module_ext & other ) : module(other), ext_impl(nullptr) {
|
||||
throw std::runtime_error("openmpt::module_ext is non-copyable");
|
||||
}
|
||||
// cppcheck-suppress operatorEqVarError
|
||||
void module_ext::operator = ( const module_ext & ) {
|
||||
throw std::runtime_error("openmpt::module_ext is non-copyable");
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
|
||||
void * module_ext::get_interface( const std::string & interface_id ) {
|
||||
return ext_impl->get_interface( interface_id );
|
||||
}
|
||||
|
||||
} // namespace openmpt
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* libopenmpt_ext.h
|
||||
* ----------------
|
||||
* Purpose: libopenmpt public c interface for libopenmpt extensions
|
||||
* Notes :
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_H
|
||||
#define LIBOPENMPT_EXT_H
|
||||
|
||||
#include "libopenmpt_config.h"
|
||||
#include "libopenmpt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \page libopenmpt_ext_c_overview libopenmpt_ext C API
|
||||
*
|
||||
* libopenmpt_ext is included in all builds by default.
|
||||
*
|
||||
* \section libopenmpt-ext-c-detailed Detailed documentation
|
||||
*
|
||||
* \ref libopenmpt_ext_c
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \defgroup libopenmpt_ext_c libopenmpt_ext C */
|
||||
|
||||
/*! \addtogroup libopenmpt_ext_c
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! \brief Opaque type representing a libopenmpt extension module
|
||||
*/
|
||||
typedef struct openmpt_module_ext openmpt_module_ext;
|
||||
|
||||
/*! \brief Construct an openmpt_module_ext
|
||||
*
|
||||
* \param stream_callbacks Input stream callback operations.
|
||||
* \param stream Input stream to load the module from.
|
||||
* \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext. May be NULL.
|
||||
* \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
|
||||
* \param errfunc Error function to define error behaviour. May be NULL.
|
||||
* \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
|
||||
* \param error Pointer to an integer where an error may get stored. May be NULL.
|
||||
* \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
* \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
* \return A pointer to the constructed openmpt_module_ext, or NULL on failure.
|
||||
* \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
|
||||
* \sa openmpt_stream_callbacks
|
||||
* \sa \ref libopenmpt_c_fileio
|
||||
* \since 0.3.0
|
||||
*/
|
||||
LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create( openmpt_stream_callbacks stream_callbacks, void * stream, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls );
|
||||
|
||||
/*! \brief Construct an openmpt_module_ext
|
||||
*
|
||||
* \param filedata Data to load the module from.
|
||||
* \param filesize Amount of data available.
|
||||
* \param logfunc Logging function where warning and errors are written. The logging function may be called throughout the lifetime of openmpt_module_ext.
|
||||
* \param loguser User-defined data associated with this module. This value will be passed to the logging callback function (logfunc)
|
||||
* \param errfunc Error function to define error behaviour. May be NULL.
|
||||
* \param erruser Error function user context. Used to pass any user-defined data associated with this module to the logging function.
|
||||
* \param error Pointer to an integer where an error may get stored. May be NULL.
|
||||
* \param error_message Pointer to a string pointer where an error message may get stored. May be NULL.
|
||||
* \param ctls A map of initial ctl values, see openmpt_module_get_ctls.
|
||||
* \return A pointer to the constructed openmpt_module_ext, or NULL on failure.
|
||||
* \remarks The input data can be discarded after an openmpt_module_ext has been constructed successfully.
|
||||
* \sa \ref libopenmpt_c_fileio
|
||||
* \since 0.3.0
|
||||
*/
|
||||
LIBOPENMPT_API openmpt_module_ext * openmpt_module_ext_create_from_memory( const void * filedata, size_t filesize, openmpt_log_func logfunc, void * loguser, openmpt_error_func errfunc, void * erruser, int * error, const char * * error_message, const openmpt_module_initial_ctl * ctls );
|
||||
|
||||
/*! \brief Unload a previously created openmpt_module_ext from memory.
|
||||
*
|
||||
* \param mod_ext The module to unload.
|
||||
*/
|
||||
LIBOPENMPT_API void openmpt_module_ext_destroy( openmpt_module_ext * mod_ext );
|
||||
|
||||
/*! \brief Retrieve the openmpt_module handle from an openmpt_module_ext handle.
|
||||
*
|
||||
* \param mod_ext The extension module handle to convert
|
||||
* \return An equivalent openmpt_module handle to pass to standard libopenmpt functions
|
||||
* \since 0.3.0
|
||||
*/
|
||||
LIBOPENMPT_API openmpt_module * openmpt_module_ext_get_module( openmpt_module_ext * mod_ext );
|
||||
|
||||
/*! Retrieve a libopenmpt extension.
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param interface_id The name of the extension interface to retrieve (e.g. LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS).
|
||||
* \param interface Appropriate structure of interface function pointers which is to be filled by this function (e.g. a pointer to a openmpt_module_ext_interface_pattern_vis structure).
|
||||
* \param interface_size Size of the interface's structure of function pointers (e.g. sizeof(openmpt_module_ext_interface_pattern_vis)).
|
||||
* \return 1 on success, 0 if the interface was not found.
|
||||
* \since 0.3.0
|
||||
*/
|
||||
LIBOPENMPT_API int openmpt_module_ext_get_interface( openmpt_module_ext * mod_ext, const char * interface_id, void * interface, size_t interface_size );
|
||||
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_PATTERN_VIS "pattern_vis"
|
||||
#endif
|
||||
|
||||
/*! Pattern command type */
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_UNKNOWN 0
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GENERAL 1
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_GLOBAL 2
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_VOLUME 3
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PANNING 4
|
||||
#define OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_PITCH 5
|
||||
|
||||
typedef struct openmpt_module_ext_interface_pattern_vis {
|
||||
/*! Get pattern command type for pattern highlighting
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param pattern The pattern whose data should be retrieved.
|
||||
* \param row The row from which the data should be retrieved.
|
||||
* \param channel The channel from which the data should be retrieved.
|
||||
* \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
|
||||
* \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type
|
||||
*/
|
||||
int ( * get_pattern_row_channel_volume_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel );
|
||||
|
||||
/*! Get pattern command type for pattern highlighting
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param pattern The pattern whose data should be retrieved.
|
||||
* \param row The row from which the data should be retrieved.
|
||||
* \param channel The channel from which the data should be retrieved.
|
||||
* \return The command type in the effect column at the given pattern position (see OPENMPT_MODULE_EXT_INTERFACE_PATTERN_VIS_EFFECT_TYPE_*)
|
||||
* \sa openmpt_module_ext_interface_pattern_vis::get_pattern_row_channel_volume_effect_type
|
||||
*/
|
||||
int ( * get_pattern_row_channel_effect_type ) ( openmpt_module_ext * mod_ext, int32_t pattern, int32_t row, int32_t channel );
|
||||
} openmpt_module_ext_interface_pattern_vis;
|
||||
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE "interactive"
|
||||
#endif
|
||||
|
||||
typedef struct openmpt_module_ext_interface_interactive {
|
||||
/*! Set the current ticks per row (speed)
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param speed The new tick count in range [1, 65535].
|
||||
* \return 1 on success, 0 on failure.
|
||||
* \remarks The tick count may be reset by pattern commands at any time.
|
||||
* \sa openmpt_module_get_current_speed
|
||||
*/
|
||||
int ( * set_current_speed ) ( openmpt_module_ext * mod_ext, int32_t speed );
|
||||
|
||||
/*! Set the current module tempo
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module.
|
||||
* \return 1 on success, 0 on failure.
|
||||
* \remarks The tempo may be reset by pattern commands at any time. Use openmpt_module_ext_interface_interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands.
|
||||
* \sa openmpt_module_get_current_tempo
|
||||
*/
|
||||
int ( * set_current_tempo ) ( openmpt_module_ext * mod_ext, int32_t tempo );
|
||||
|
||||
/*! Set the current module tempo factor without affecting playback pitch
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo.
|
||||
* \return 1 on success, 0 on failure.
|
||||
* \remarks Modifying the tempo without applying the same pitch factor using openmpt_module_ext_interface_interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
* \sa openmpt_module_ext_interface_interactive::get_tempo_factor
|
||||
*/
|
||||
int ( * set_tempo_factor ) ( openmpt_module_ext * mod_ext, double factor );
|
||||
|
||||
/*! Gets the current module tempo factor
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \return The current tempo factor.
|
||||
* \sa openmpt_module_ext_interface_interactive::set_tempo_factor
|
||||
*/
|
||||
double ( * get_tempo_factor ) ( openmpt_module_ext * mod_ext );
|
||||
|
||||
/*! Set the current module pitch factor without affecting playback speed
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch.
|
||||
* \return 1 on success, 0 on failure.
|
||||
* \remarks Modifying the pitch without applying the the same tempo factor using openmpt_module_ext_interface_interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
* \remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )`
|
||||
* \sa openmpt_module_ext_interface_interactive::get_pitch_factor
|
||||
*/
|
||||
int ( * set_pitch_factor ) ( openmpt_module_ext * mod_ext, double factor );
|
||||
|
||||
/*! Gets the current module pitch factor
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \return The current pitch factor.
|
||||
* \sa openmpt_module_ext_interface_interactive::set_pitch_factor
|
||||
*/
|
||||
double ( * get_pitch_factor ) ( openmpt_module_ext * mod_ext );
|
||||
|
||||
/*! Set the current global volume
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param volume The new global volume in range [0.0, 1.0]
|
||||
* \return 1 on success, 0 on failure.
|
||||
* \remarks The global volume may be reset by pattern commands at any time. Use openmpt_module_set_render_param to apply a global overall volume factor that is independent of pattern commands.
|
||||
* \sa openmpt_module_ext_interface_interactive::get_global_volume
|
||||
*/
|
||||
int ( * set_global_volume ) ( openmpt_module_ext * mod_ext, double volume );
|
||||
|
||||
/*! Get the current global volume
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \return The current global volume in range [0.0, 1.0]
|
||||
* \sa openmpt_module_ext_interface_interactive::set_global_volume
|
||||
*/
|
||||
double ( * get_global_volume ) ( openmpt_module_ext * mod_ext );
|
||||
|
||||
/*! Set the current channel volume for a channel
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose volume should be set, in range [0, openmpt_module_get_num_channels()[
|
||||
* \param volume The new channel volume in range [0.0, 1.0]
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \remarks The channel volume may be reset by pattern commands at any time.
|
||||
* \sa openmpt_module_ext_interface_interactive::get_channel_volume
|
||||
*/
|
||||
int ( * set_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel, double volume );
|
||||
|
||||
/*! Get the current channel volume for a channel
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose volume should be retrieved, in range [0, openmpt_module_get_num_channels()[
|
||||
* \return The current channel volume in range [0.0, 1.0]
|
||||
* \sa openmpt_module_ext_interface_interactive::set_channel_volume
|
||||
*/
|
||||
double ( * get_channel_volume ) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
/*! Set the current mute status for a channel
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose mute status should be set, in range [0, openmpt_module_get_num_channels()[
|
||||
* \param mute The new mute status. true is muted, false is unmuted.
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \sa openmpt_module_ext_interface_interactive::get_channel_mute_status
|
||||
*/
|
||||
int ( * set_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel, int mute );
|
||||
|
||||
/*! Get the current mute status for a channel
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose mute status should be retrieved, in range [0, openmpt_module_get_num_channels()[
|
||||
* \return The current channel mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range
|
||||
* \sa openmpt_module_ext_interface_interactive::set_channel_mute_status
|
||||
*/
|
||||
int ( * get_channel_mute_status ) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
/*! Set the current mute status for an instrument
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param instrument The instrument whose mute status should be set, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
* \param mute The new mute status. true is muted, false is unmuted.
|
||||
* \return 1 on success, 0 on failure (instrument out of range).
|
||||
* \sa openmpt_module_ext_interface_interactive::get_instrument_mute_status
|
||||
*/
|
||||
int ( * set_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument, int mute );
|
||||
|
||||
/*! Get the current mute status for an instrument
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param instrument The instrument whose mute status should be retrieved, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
* \return The current instrument mute status. 1 is muted, 0 is unmuted, -1 means the instrument was out of range
|
||||
* \sa openmpt_module_ext_interface_interactive::set_instrument_mute_status
|
||||
*/
|
||||
int ( * get_instrument_mute_status ) ( openmpt_module_ext * mod_ext, int32_t instrument );
|
||||
|
||||
/*! Play a note using the specified instrument
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param instrument The instrument that should be played, in range [0, openmpt_module_get_num_instruments()[ if openmpt_module_get_num_instruments is not 0, otherwise in [0, openmpt_module_get_num_samples()[
|
||||
* \param note The note to play, in rage [0, 119]. 60 is the middle C.
|
||||
* \param volume The volume at which the note should be triggered, in range [0.0, 1.0]
|
||||
* \param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center.
|
||||
* \return The channel on which the note is played. This can pe be passed to openmpt_module_ext_interface_interactive::stop_note to stop the note. -1 means that no channel could be allocated and the note is not played.
|
||||
* \sa openmpt_module_ext_interface_interactive::stop_note
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_off
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_fade
|
||||
*/
|
||||
int32_t ( * play_note ) ( openmpt_module_ext * mod_ext, int32_t instrument, int32_t note, double volume, double panning );
|
||||
|
||||
/*! Stop the note playing on the specified channel
|
||||
*
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel on which the note should be stopped. This is the value returned by a previous play_note call.
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \sa openmpt_module_ext_interface_interactive::play_note
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_off
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_fade
|
||||
*/
|
||||
int ( * stop_note ) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
} openmpt_module_ext_interface_interactive;
|
||||
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE2
|
||||
#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE2 "interactive2"
|
||||
#endif
|
||||
|
||||
typedef struct openmpt_module_ext_interface_interactive2 {
|
||||
//! Sends a key-off command for the note playing on the specified channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel on which the key-off event should be triggered. This is the value returned by a previous play_note call.
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \remarks This method releases envelopes and sample sustain loops. If the sample has no sustain loop, or if the module does not use instruments, it does nothing.
|
||||
* \sa openmpt_module_ext_interface_interactive::play_note
|
||||
* \sa openmpt_module_ext_interface_interactive::stop_note
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_fade
|
||||
* \since 0.6.0
|
||||
*/
|
||||
int ( *note_off ) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
//! Sends a note fade command for the note playing on the specified channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel on which the note should be faded. This is the value returned by a previous play_note call.
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \remarks This method uses the instrument's fade-out value. If the module does not use instruments, or the instrument's fade-out value is 0, it does nothing.
|
||||
* \sa openmpt_module_ext_interface_interactive::play_note
|
||||
* \sa openmpt_module_ext_interface_interactive::stop_note
|
||||
* \sa openmpt_module_ext_interface_interactive2::note_fade
|
||||
* \since 0.6.0
|
||||
*/
|
||||
int ( *note_fade ) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
//! Set the current panning for a channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel that should be panned. This is the value returned by a previous play_note call.
|
||||
* \param panning The panning position to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
* \return 1 on success, 0 on failure (channel out of range).
|
||||
* \remarks This command affects subsequent notes played on the same channel, and may itself be overridden by subsequent panning commands encountered in the module itself.
|
||||
* \sa openmpt_module_ext_interface_interactive2::get_channel_panning
|
||||
* \since 0.6.0
|
||||
*/
|
||||
int ( *set_channel_panning) ( openmpt_module_ext * mod_ext, int32_t channel, double panning );
|
||||
|
||||
//! Get the current panning position for a channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose panning should be retrieved. This is the value returned by a previous play_note call.
|
||||
* \return The current channel panning, in range [-1.0, 1.0], 0.0 is center.
|
||||
* \sa openmpt_module_ext_interface_interactive2::set_channel_panning
|
||||
* \since 0.6.0
|
||||
*/
|
||||
double (*get_channel_panning) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
//! Set the finetune for the currently playing note on a channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose finetune will be changed, in range [0, openmpt::module::get_num_channels()[
|
||||
* \param finetune The finetune to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
* \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
* \remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
* \remarks This command does not affect subsequent notes played on the same channel, but may itself be overridden by subsequent finetune commands encountered in the module itself.
|
||||
* \sa openmpt_module_ext_interface_interactive2::get_note_finetune
|
||||
* \since 0.6.0
|
||||
*/
|
||||
int ( *set_note_finetune) ( openmpt_module_ext * mod_ext, int32_t channel, double finetune );
|
||||
|
||||
//! Get the finetune for the currently playing note on a channel
|
||||
/*!
|
||||
* \param mod_ext The module handle to work on.
|
||||
* \param channel The channel whose finetune should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
* \return The current channel finetune, in range [-1.0, 1.0], 0.0 is center.
|
||||
* \remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
* \throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
* \sa openmpt_module_ext_interface_interactive2::set_note_finetune
|
||||
* \since 0.6.0
|
||||
*/
|
||||
double (*get_note_finetune) ( openmpt_module_ext * mod_ext, int32_t channel );
|
||||
|
||||
} openmpt_module_ext_interface_interactive2;
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* LIBOPENMPT_EXT_H */
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* libopenmpt_ext.hpp
|
||||
* ------------------
|
||||
* Purpose: libopenmpt public c++ interface for libopenmpt extensions
|
||||
* Notes :
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_HPP
|
||||
#define LIBOPENMPT_EXT_HPP
|
||||
|
||||
#include "libopenmpt_config.h"
|
||||
#include "libopenmpt.hpp"
|
||||
|
||||
/*!
|
||||
* \page libopenmpt_ext_cpp_overview libopenmpt_ext C++ API
|
||||
*
|
||||
* libopenmpt_ext is now included in all builds by default.
|
||||
*
|
||||
* \section libopenmpt-ext-cpp-detailed Detailed documentation
|
||||
*
|
||||
* \ref libopenmpt_ext_cpp
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \defgroup libopenmpt_ext_cpp libopenmpt_ext C++ */
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
/*! \addtogroup libopenmpt_ext_cpp
|
||||
@{
|
||||
*/
|
||||
|
||||
class module_ext_impl;
|
||||
|
||||
class LIBOPENMPT_CXX_API module_ext : public module {
|
||||
|
||||
private:
|
||||
module_ext_impl * ext_impl;
|
||||
private:
|
||||
// non-copyable
|
||||
module_ext( const module_ext & );
|
||||
void operator = ( const module_ext & );
|
||||
public:
|
||||
module_ext( std::istream & stream, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const std::vector<std::byte> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const std::vector<std::uint8_t> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const std::vector<char> & data, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const std::byte * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const std::uint8_t * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const char * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
module_ext( const void * data, std::size_t size, std::ostream & log = std::clog, const std::map< std::string, std::string > & ctls = detail::initial_ctls_map() );
|
||||
virtual ~module_ext();
|
||||
|
||||
public:
|
||||
|
||||
//! Retrieve a libopenmpt extension.
|
||||
/*! Example: Retrieving the interactive extension to change the tempo of a module:
|
||||
\code{.cpp}
|
||||
openmpt::module_ext *mod = new openmpt::module_ext( stream );
|
||||
#ifdef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE
|
||||
openmpt::ext::interactive *interactive = static_cast<openmpt::ext::interactive *>( self->mod->get_interface( openmpt::ext::interactive_id ) );
|
||||
if ( interactive ) {
|
||||
interactive->set_tempo_factor( 2.0 ); // play module at double speed
|
||||
} else {
|
||||
// interface not available
|
||||
}
|
||||
#else
|
||||
// interfae not available
|
||||
#endif
|
||||
\endcode
|
||||
\param interface_id The name of the extension interface to retrieve.
|
||||
\return The interface object. This may be a nullptr if the extension was not found.
|
||||
*/
|
||||
void * get_interface( const std::string & interface_id );
|
||||
|
||||
}; // class module_ext
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
namespace ext {
|
||||
|
||||
/*! \addtogroup libopenmpt_ext_cpp
|
||||
@{
|
||||
*/
|
||||
|
||||
#define LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(name) \
|
||||
static const char name ## _id [] = # name ; \
|
||||
class name; \
|
||||
/**/
|
||||
|
||||
#define LIBOPENMPT_EXT_CXX_INTERFACE(name) \
|
||||
protected: \
|
||||
name () {} \
|
||||
virtual ~ name () {} \
|
||||
public: \
|
||||
/**/
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS
|
||||
#define LIBOPENMPT_EXT_INTERFACE_PATTERN_VIS
|
||||
#endif
|
||||
|
||||
LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(pattern_vis)
|
||||
|
||||
class pattern_vis {
|
||||
|
||||
LIBOPENMPT_EXT_CXX_INTERFACE(pattern_vis)
|
||||
|
||||
//! Pattern command type
|
||||
enum effect_type {
|
||||
|
||||
effect_unknown = 0,
|
||||
effect_general = 1,
|
||||
effect_global = 2,
|
||||
effect_volume = 3,
|
||||
effect_panning = 4,
|
||||
effect_pitch = 5
|
||||
|
||||
}; // enum effect_type
|
||||
|
||||
//! Get pattern command type for pattern highlighting
|
||||
/*!
|
||||
\param pattern The pattern whose data should be retrieved.
|
||||
\param row The row from which the data should be retrieved.
|
||||
\param channel The channel from which the data should be retrieved.
|
||||
\return The command type in the effect column at the given pattern position (see openmpt::ext::pattern_vis::effect_type)
|
||||
\sa openmpt::ext::pattern_vis::get_pattern_row_channel_effect_type
|
||||
*/
|
||||
virtual effect_type get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0;
|
||||
|
||||
//! Get pattern command type for pattern highlighting
|
||||
/*!
|
||||
\param pattern The pattern whose data should be retrieved.
|
||||
\param row The row from which the data should be retrieved.
|
||||
\param channel The channel from which the data should be retrieved.
|
||||
\return The command type in the volume column at the given pattern position (see openmpt::ext::pattern_vis::effect_type)
|
||||
\sa openmpt::ext::pattern_vis::get_pattern_row_channel_volume_effect_type
|
||||
*/
|
||||
virtual effect_type get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const = 0;
|
||||
|
||||
}; // class pattern_vis
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE
|
||||
#define LIBOPENMPT_EXT_INTERFACE_INTERACTIVE
|
||||
#endif
|
||||
|
||||
LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(interactive)
|
||||
|
||||
class interactive {
|
||||
|
||||
LIBOPENMPT_EXT_CXX_INTERFACE(interactive)
|
||||
|
||||
//! Set the current ticks per row (speed)
|
||||
/*!
|
||||
\param speed The new tick count in range [1, 65535].
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the speed is outside the specified range.
|
||||
\remarks The tick count may be reset by pattern commands at any time.
|
||||
\sa openmpt::module::get_current_speed
|
||||
*/
|
||||
virtual void set_current_speed( std::int32_t speed ) = 0;
|
||||
|
||||
//! Set the current module tempo
|
||||
/*!
|
||||
\param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the tempo is outside the specified range.
|
||||
\remarks The tempo may be reset by pattern commands at any time. Use openmpt::ext:interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands.
|
||||
\sa openmpt::module::get_current_tempo
|
||||
*/
|
||||
virtual void set_current_tempo( std::int32_t tempo ) = 0;
|
||||
|
||||
//! Set the current module tempo factor without affecting playback pitch
|
||||
/*!
|
||||
\param factor The new tempo factor in range ]0.0, 4.0] - 1.0 means unmodified tempo.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range.
|
||||
\remarks Modifying the tempo without applying the same pitch factor using openmpt::ext::interactive::set_pitch_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
\sa openmpt::ext::interactive::get_tempo_factor
|
||||
*/
|
||||
virtual void set_tempo_factor( double factor ) = 0;
|
||||
|
||||
//! Gets the current module tempo factor
|
||||
/*!
|
||||
\return The current tempo factor.
|
||||
\sa openmpt::ext::interactive::set_tempo_factor
|
||||
*/
|
||||
virtual double get_tempo_factor( ) const = 0;
|
||||
|
||||
//! Set the current module pitch factor without affecting playback speed
|
||||
/*!
|
||||
\param factor The new pitch factor in range ]0.0, 4.0] - 1.0 means unmodified pitch.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the factor is outside the specified range.
|
||||
\remarks Modifying the pitch without applying the the same tempo factor using openmpt::ext::interactive::set_tempo_factor may cause rhythmic samples (e.g. drum loops) to go out of sync.
|
||||
\remarks To shift the pich by `n` semitones, the parameter can be calculated as follows: `pow( 2.0, n / 12.0 )`
|
||||
\sa openmpt::ext::interactive::get_pitch_factor
|
||||
*/
|
||||
virtual void set_pitch_factor( double factor ) = 0;
|
||||
|
||||
//! Gets the current module pitch factor
|
||||
/*!
|
||||
\return The current pitch factor.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the pitch is outside the specified range.
|
||||
\sa openmpt::ext::interactive::set_pitch_factor
|
||||
*/
|
||||
virtual double get_pitch_factor( ) const = 0;
|
||||
|
||||
//! Set the current global volume
|
||||
/*!
|
||||
\param volume The new global volume in range [0.0, 1.0]
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the volume is outside the specified range.
|
||||
\remarks The global volume may be reset by pattern commands at any time. Use openmpt::module::set_render_param to apply a global overall volume factor that is independent of pattern commands.
|
||||
\sa openmpt::ext::interactive::get_global_volume
|
||||
*/
|
||||
virtual void set_global_volume( double volume ) = 0;
|
||||
|
||||
//! Get the current global volume
|
||||
/*!
|
||||
\return The current global volume in range [0.0, 1.0]
|
||||
\sa openmpt::ext::interactive::set_global_volume
|
||||
*/
|
||||
virtual double get_global_volume( ) const = 0;
|
||||
|
||||
//! Set the current channel volume for a channel
|
||||
/*!
|
||||
\param channel The channel whose volume should be set, in range [0, openmpt::module::get_num_channels()[
|
||||
\param volume The new channel volume in range [0.0, 1.0]
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel or volume is outside the specified range.
|
||||
\remarks The channel volume may be reset by pattern commands at any time.
|
||||
\sa openmpt::ext::interactive::get_channel_volume
|
||||
*/
|
||||
virtual void set_channel_volume( std::int32_t channel, double volume ) = 0;
|
||||
|
||||
//! Get the current channel volume for a channel
|
||||
/*!
|
||||
\param channel The channel whose volume should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
\return The current channel volume in range [0.0, 1.0]
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\sa openmpt::ext::interactive::set_channel_volume
|
||||
*/
|
||||
virtual double get_channel_volume( std::int32_t channel ) const = 0;
|
||||
|
||||
//! Set the current mute status for a channel
|
||||
/*!
|
||||
\param channel The channel whose mute status should be set, in range [0, openmpt::module::get_num_channels()[
|
||||
\param mute The new mute status. true is muted, false is unmuted.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\sa openmpt::ext::interactive::get_channel_mute_status
|
||||
*/
|
||||
virtual void set_channel_mute_status( std::int32_t channel, bool mute ) = 0;
|
||||
|
||||
//! Get the current mute status for a channel
|
||||
/*!
|
||||
\param channel The channel whose mute status should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
\return The current channel mute status. true is muted, false is unmuted.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\sa openmpt::ext::interactive::set_channel_mute_status
|
||||
*/
|
||||
virtual bool get_channel_mute_status( std::int32_t channel ) const = 0;
|
||||
|
||||
//! Set the current mute status for an instrument
|
||||
/*!
|
||||
\param instrument The instrument whose mute status should be set, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[
|
||||
\param mute The new mute status. true is muted, false is unmuted.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range.
|
||||
\sa openmpt::ext::interactive::get_instrument_mute_status
|
||||
*/
|
||||
virtual void set_instrument_mute_status( std::int32_t instrument, bool mute ) = 0;
|
||||
|
||||
//! Get the current mute status for an instrument
|
||||
/*!
|
||||
\param instrument The instrument whose mute status should be retrieved, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[
|
||||
\return The current instrument mute status. true is muted, false is unmuted.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument is outside the specified range.
|
||||
\sa openmpt::ext::interactive::set_instrument_mute_status
|
||||
*/
|
||||
virtual bool get_instrument_mute_status( std::int32_t instrument ) const = 0;
|
||||
|
||||
//! Play a note using the specified instrument
|
||||
/*!
|
||||
\param instrument The instrument that should be played, in range [0, openmpt::module::get_num_instruments()[ if openmpt::module::get_num_instruments is not 0, otherwise in [0, openmpt::module::get_num_samples()[
|
||||
\param note The note to play, in rage [0, 119]. 60 is the middle C.
|
||||
\param volume The volume at which the note should be triggered, in range [0.0, 1.0]
|
||||
\param panning The panning position at which the note should be triggered, in range [-1.0, 1.0], 0.0 is center.
|
||||
\return The channel on which the note is played. This can pe be passed to openmpt::ext::interactive::stop_note to stop the note.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the instrument or note is outside the specified range.
|
||||
\sa openmpt::ext::interactive::stop_note
|
||||
\sa openmpt::ext::interactive2::note_off
|
||||
\sa openmpt::ext::interactive2::note_fade
|
||||
*/
|
||||
virtual std::int32_t play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) = 0;
|
||||
|
||||
//! Stop the note playing on the specified channel
|
||||
/*!
|
||||
\param channel The channel on which the note should be stopped. This is the value returned by a previous play_note call.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\sa openmpt::ext::interactive::play_note
|
||||
\sa openmpt::ext::interactive2::note_off
|
||||
\sa openmpt::ext::interactive2::note_fade
|
||||
*/
|
||||
virtual void stop_note( std::int32_t channel ) = 0;
|
||||
|
||||
}; // class interactive
|
||||
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE2
|
||||
#define LIBOPENMPT_EXT_INTERFACE_INTERACTIVE2
|
||||
#endif
|
||||
|
||||
LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(interactive2)
|
||||
|
||||
class interactive2 {
|
||||
|
||||
LIBOPENMPT_EXT_CXX_INTERFACE(interactive2)
|
||||
|
||||
//! Sends a key-off command for the note playing on the specified channel
|
||||
/*!
|
||||
\param channel The channel on which the key-off event should be triggered. This is the value returned by a previous play_note call.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\remarks This method releases envelopes and sample sustain loops. If the sample has no sustain loop, or if the module does not use instruments, it does nothing.
|
||||
\sa openmpt::ext::interactive::play_note
|
||||
\sa openmpt::ext::interactive::stop_note
|
||||
\sa openmpt::ext::interactive2::note_fade
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual void note_off(int32_t channel ) = 0;
|
||||
|
||||
//! Sends a note fade command for the note playing on the specified channel
|
||||
/*!
|
||||
\param channel The channel on which the note should be faded. This is the value returned by a previous play_note call.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\remarks This method uses the instrument's fade-out value. If the module does not use instruments, or the instrument's fade-out value is 0, it does nothing.
|
||||
\sa openmpt::ext::interactive::play_note
|
||||
\sa openmpt::ext::interactive::stop_note
|
||||
\sa openmpt::ext::interactive2::note_off
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual void note_fade(int32_t channel) = 0;
|
||||
|
||||
//! Set the current panning position for a channel
|
||||
/*!
|
||||
\param channel The channel whose panning will be changed, in range [0, openmpt::module::get_num_channels()[
|
||||
\param panning The panning position to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\remarks This command affects subsequent notes played on the same channel, and may itself be overridden by subsequent panning commands encountered in the module itself.
|
||||
\sa openmpt::ext::interactive2::get_channel_panning
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual void set_channel_panning(int32_t channel, double panning ) = 0;
|
||||
|
||||
//! Get the current panning position for a channel
|
||||
/*!
|
||||
\param channel The channel whose panning should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
\return The current channel panning, in range [-1.0, 1.0], 0.0 is center.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\sa openmpt::ext::interactive2::set_channel_panning
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual double get_channel_panning( int32_t channel ) = 0;
|
||||
|
||||
//! Set the finetune for the currently playing note on a channel
|
||||
/*!
|
||||
\param channel The channel whose finetune will be changed, in range [0, openmpt::module::get_num_channels()[
|
||||
\param finetune The finetune to set on the channel, in range [-1.0, 1.0], 0.0 is center.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel index is invalid.
|
||||
\remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
\remarks This command does not affect subsequent notes played on the same channel, but may itself be overridden by subsequent finetune commands encountered in the module itself.
|
||||
\sa openmpt::ext::interactive2::get_note_finetune
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual void set_note_finetune(int32_t channel, double finetune ) = 0;
|
||||
|
||||
//! Get the finetune for the currently playing note on a channel
|
||||
/*!
|
||||
\param channel The channel whose finetune should be retrieved, in range [0, openmpt::module::get_num_channels()[
|
||||
\return The current channel finetune, in range [-1.0, 1.0], 0.0 is center.
|
||||
\throws openmpt::exception Throws an exception derived from openmpt::exception if the channel is outside the specified range.
|
||||
\remarks The finetune range depends on the pitch wheel depth of the instrument playing on the current channel; for sample-based modules, the depth of this command is fixed to +/-1 semitone.
|
||||
\sa openmpt::ext::interactive2::set_note_finetune
|
||||
\since 0.6.0
|
||||
*/
|
||||
virtual double get_note_finetune( int32_t channel ) = 0;
|
||||
|
||||
}; // class interactive
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
#undef LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE
|
||||
#undef LIBOPENMPT_EXT_CXX_INTERFACE
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
} // namespace ext
|
||||
|
||||
} // namespace openmpt
|
||||
|
||||
#endif // LIBOPENMPT_EXT_HPP
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* libopenmpt_ext_impl.cpp
|
||||
* -----------------------
|
||||
* Purpose: libopenmpt extensions - implementation
|
||||
* Notes :
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include "common/stdafx.h"
|
||||
|
||||
#include "libopenmpt_internal.h"
|
||||
#include "libopenmpt_ext.hpp"
|
||||
|
||||
#include "libopenmpt_ext_impl.hpp"
|
||||
|
||||
#include "mpt/base/saturate_round.hpp"
|
||||
|
||||
#include "soundlib/Sndfile.h"
|
||||
|
||||
// assume OPENMPT_NAMESPACE is OpenMPT
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
module_ext_impl::module_ext_impl( callback_stream_wrapper stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( stream, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( std::istream & stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( stream, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const std::vector<std::byte> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const std::vector<std::uint8_t> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const std::vector<char> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const std::byte * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const char * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
module_ext_impl::module_ext_impl( const void * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls ) : module_impl( data, size, std::move(log), ctls ) {
|
||||
ctor();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void module_ext_impl::ctor() {
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
module_ext_impl::~module_ext_impl() {
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void * module_ext_impl::get_interface( const std::string & interface_id ) {
|
||||
if ( interface_id.empty() ) {
|
||||
return 0;
|
||||
} else if ( interface_id == ext::pattern_vis_id ) {
|
||||
return dynamic_cast< ext::pattern_vis * >( this );
|
||||
} else if ( interface_id == ext::interactive_id ) {
|
||||
return dynamic_cast< ext::interactive * >( this );
|
||||
} else if ( interface_id == ext::interactive2_id ) {
|
||||
return dynamic_cast< ext::interactive2 * >( this );
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// pattern_vis
|
||||
|
||||
module_ext_impl::effect_type module_ext_impl::get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const {
|
||||
std::uint8_t byte = get_pattern_row_channel_command( pattern, row, channel, module::command_volumeffect );
|
||||
switch ( OpenMPT::ModCommand::GetVolumeEffectType( byte ) ) {
|
||||
case OpenMPT::EFFECT_TYPE_NORMAL : return effect_general; break;
|
||||
case OpenMPT::EFFECT_TYPE_GLOBAL : return effect_global ; break;
|
||||
case OpenMPT::EFFECT_TYPE_VOLUME : return effect_volume ; break;
|
||||
case OpenMPT::EFFECT_TYPE_PANNING: return effect_panning; break;
|
||||
case OpenMPT::EFFECT_TYPE_PITCH : return effect_pitch ; break;
|
||||
default: return effect_unknown; break;
|
||||
}
|
||||
}
|
||||
|
||||
module_ext_impl::effect_type module_ext_impl::get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const {
|
||||
std::uint8_t byte = get_pattern_row_channel_command( pattern, row, channel, module::command_effect );
|
||||
switch (OpenMPT::ModCommand::GetEffectType( byte ) ) {
|
||||
case OpenMPT::EFFECT_TYPE_NORMAL : return effect_general; break;
|
||||
case OpenMPT::EFFECT_TYPE_GLOBAL : return effect_global ; break;
|
||||
case OpenMPT::EFFECT_TYPE_VOLUME : return effect_volume ; break;
|
||||
case OpenMPT::EFFECT_TYPE_PANNING: return effect_panning; break;
|
||||
case OpenMPT::EFFECT_TYPE_PITCH : return effect_pitch ; break;
|
||||
default: return effect_unknown; break;
|
||||
}
|
||||
}
|
||||
|
||||
// interactive
|
||||
|
||||
void module_ext_impl::set_current_speed( std::int32_t speed ) {
|
||||
if ( speed < 1 || speed > 65535 ) {
|
||||
throw openmpt::exception("invalid tick count");
|
||||
}
|
||||
m_sndFile->m_PlayState.m_nMusicSpeed = speed;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_current_tempo( std::int32_t tempo ) {
|
||||
if ( tempo < 32 || tempo > 512 ) {
|
||||
throw openmpt::exception("invalid tempo");
|
||||
}
|
||||
m_sndFile->m_PlayState.m_nMusicTempo.Set( tempo );
|
||||
}
|
||||
|
||||
void module_ext_impl::set_tempo_factor( double factor ) {
|
||||
if ( factor <= 0.0 || factor > 4.0 ) {
|
||||
throw openmpt::exception("invalid tempo factor");
|
||||
}
|
||||
m_sndFile->m_nTempoFactor = mpt::saturate_round<uint32_t>( 65536.0 / factor );
|
||||
m_sndFile->RecalculateSamplesPerTick();
|
||||
}
|
||||
|
||||
double module_ext_impl::get_tempo_factor( ) const {
|
||||
return 65536.0 / m_sndFile->m_nTempoFactor;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_pitch_factor( double factor ) {
|
||||
if ( factor <= 0.0 || factor > 4.0 ) {
|
||||
throw openmpt::exception("invalid pitch factor");
|
||||
}
|
||||
m_sndFile->m_nFreqFactor = mpt::saturate_round<uint32_t>( 65536.0 * factor );
|
||||
m_sndFile->RecalculateSamplesPerTick();
|
||||
}
|
||||
|
||||
double module_ext_impl::get_pitch_factor( ) const {
|
||||
return m_sndFile->m_nFreqFactor / 65536.0;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_global_volume( double volume ) {
|
||||
if ( volume < 0.0 || volume > 1.0 ) {
|
||||
throw openmpt::exception("invalid global volume");
|
||||
}
|
||||
m_sndFile->m_PlayState.m_nGlobalVolume = mpt::saturate_round<uint32_t>( volume * MAX_GLOBAL_VOLUME );
|
||||
}
|
||||
|
||||
double module_ext_impl::get_global_volume( ) const {
|
||||
return m_sndFile->m_PlayState.m_nGlobalVolume / static_cast<double>( MAX_GLOBAL_VOLUME );
|
||||
}
|
||||
|
||||
void module_ext_impl::set_channel_volume( std::int32_t channel, double volume ) {
|
||||
if ( channel < 0 || channel >= get_num_channels() ) {
|
||||
throw openmpt::exception("invalid channel");
|
||||
}
|
||||
if ( volume < 0.0 || volume > 1.0 ) {
|
||||
throw openmpt::exception("invalid global volume");
|
||||
}
|
||||
m_sndFile->m_PlayState.Chn[channel].nGlobalVol = mpt::saturate_round<std::int32_t>(volume * 64.0);
|
||||
}
|
||||
|
||||
double module_ext_impl::get_channel_volume( std::int32_t channel ) const {
|
||||
if ( channel < 0 || channel >= get_num_channels() ) {
|
||||
throw openmpt::exception("invalid channel");
|
||||
}
|
||||
return m_sndFile->m_PlayState.Chn[channel].nGlobalVol / 64.0;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_channel_mute_status( std::int32_t channel, bool mute ) {
|
||||
if ( channel < 0 || channel >= get_num_channels() ) {
|
||||
throw openmpt::exception("invalid channel");
|
||||
}
|
||||
m_sndFile->ChnSettings[channel].dwFlags.set( OpenMPT::CHN_MUTE | OpenMPT::CHN_SYNCMUTE , mute );
|
||||
m_sndFile->m_PlayState.Chn[channel].dwFlags.set( OpenMPT::CHN_MUTE | OpenMPT::CHN_SYNCMUTE , mute );
|
||||
|
||||
// Also update NNA channels
|
||||
for ( OpenMPT::CHANNELINDEX i = m_sndFile->GetNumChannels(); i < OpenMPT::MAX_CHANNELS; i++)
|
||||
{
|
||||
if ( m_sndFile->m_PlayState.Chn[i].nMasterChn == channel + 1)
|
||||
{
|
||||
m_sndFile->m_PlayState.Chn[i].dwFlags.set( OpenMPT::CHN_MUTE | OpenMPT::CHN_SYNCMUTE, mute );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool module_ext_impl::get_channel_mute_status( std::int32_t channel ) const {
|
||||
if ( channel < 0 || channel >= get_num_channels() ) {
|
||||
throw openmpt::exception("invalid channel");
|
||||
}
|
||||
return m_sndFile->m_PlayState.Chn[channel].dwFlags[OpenMPT::CHN_MUTE | OpenMPT::CHN_SYNCMUTE];
|
||||
}
|
||||
|
||||
void module_ext_impl::set_instrument_mute_status( std::int32_t instrument, bool mute ) {
|
||||
const bool instrument_mode = get_num_instruments() != 0;
|
||||
const std::int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples();
|
||||
if ( instrument < 0 || instrument >= max_instrument ) {
|
||||
throw openmpt::exception("invalid instrument");
|
||||
}
|
||||
if ( instrument_mode ) {
|
||||
if ( m_sndFile->Instruments[instrument + 1] != nullptr ) {
|
||||
m_sndFile->Instruments[instrument + 1]->dwFlags.set( OpenMPT::INS_MUTE, mute );
|
||||
}
|
||||
} else {
|
||||
m_sndFile->GetSample( static_cast<OpenMPT::SAMPLEINDEX>( instrument + 1 ) ).uFlags.set( OpenMPT::CHN_MUTE, mute ) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool module_ext_impl::get_instrument_mute_status( std::int32_t instrument ) const {
|
||||
const bool instrument_mode = get_num_instruments() != 0;
|
||||
const std::int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples();
|
||||
if ( instrument < 0 || instrument >= max_instrument ) {
|
||||
throw openmpt::exception("invalid instrument");
|
||||
}
|
||||
if ( instrument_mode ) {
|
||||
if ( m_sndFile->Instruments[instrument + 1] != nullptr ) {
|
||||
return m_sndFile->Instruments[instrument + 1]->dwFlags[OpenMPT::INS_MUTE];
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return m_sndFile->GetSample( static_cast<OpenMPT::SAMPLEINDEX>( instrument + 1 ) ).uFlags[OpenMPT::CHN_MUTE];
|
||||
}
|
||||
}
|
||||
|
||||
std::int32_t module_ext_impl::play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) {
|
||||
const bool instrument_mode = get_num_instruments() != 0;
|
||||
const std::int32_t max_instrument = instrument_mode ? get_num_instruments() : get_num_samples();
|
||||
if ( instrument < 0 || instrument >= max_instrument ) {
|
||||
throw openmpt::exception("invalid instrument");
|
||||
}
|
||||
note += OpenMPT::NOTE_MIN;
|
||||
if ( note < OpenMPT::NOTE_MIN || note > OpenMPT::NOTE_MAX ) {
|
||||
throw openmpt::exception("invalid note");
|
||||
}
|
||||
|
||||
// Find a free channel
|
||||
OpenMPT::CHANNELINDEX free_channel = m_sndFile->GetNNAChannel( OpenMPT::CHANNELINDEX_INVALID );
|
||||
if ( free_channel == OpenMPT::CHANNELINDEX_INVALID ) {
|
||||
free_channel = OpenMPT::MAX_CHANNELS - 1;
|
||||
}
|
||||
|
||||
OpenMPT::ModChannel &chn = m_sndFile->m_PlayState.Chn[free_channel];
|
||||
chn.Reset( OpenMPT::ModChannel::resetTotal, *m_sndFile, OpenMPT::CHANNELINDEX_INVALID, OpenMPT::CHN_MUTE );
|
||||
chn.nMasterChn = 0; // remove NNA association
|
||||
chn.nNewNote = chn.nLastNote = static_cast<std::uint8_t>(note);
|
||||
chn.ResetEnvelopes();
|
||||
m_sndFile->InstrumentChange(chn, instrument + 1);
|
||||
chn.nFadeOutVol = 0x10000;
|
||||
m_sndFile->NoteChange(chn, note, false, true, true);
|
||||
chn.nPan = mpt::saturate_round<std::int32_t>( OpenMPT::Clamp( panning * 128.0, -128.0, 128.0 ) + 128.0 );
|
||||
chn.nVolume = mpt::saturate_round<std::int32_t>( OpenMPT::Clamp( volume * 256.0, 0.0, 256.0 ) );
|
||||
|
||||
// Remove channel from list of mixed channels to fix https://bugs.openmpt.org/view.php?id=209
|
||||
// This is required because a previous note on the same channel might have just stopped playing,
|
||||
// but the channel is still in the mix list.
|
||||
// Since the channel volume / etc is only updated every tick in CSoundFile::ReadNote, and we
|
||||
// do not want to duplicate mixmode-dependant logic here, CSoundFile::CreateStereoMix may already
|
||||
// try to mix our newly set up channel at volume 0 if we don't remove it from the list.
|
||||
auto mix_begin = std::begin( m_sndFile->m_PlayState.ChnMix );
|
||||
auto mix_end = std::remove( mix_begin, mix_begin + m_sndFile->m_nMixChannels, free_channel );
|
||||
m_sndFile->m_nMixChannels = static_cast<OpenMPT::CHANNELINDEX>( std::distance( mix_begin, mix_end ) );
|
||||
|
||||
return free_channel;
|
||||
}
|
||||
|
||||
void module_ext_impl::stop_note( std::int32_t channel ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception("invalid channel");
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
chn.nLength = 0;
|
||||
chn.pCurrentSample = nullptr;
|
||||
}
|
||||
|
||||
void module_ext_impl::note_off(int32_t channel ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
chn.dwFlags |= OpenMPT::CHN_KEYOFF;
|
||||
}
|
||||
|
||||
void module_ext_impl::note_fade(int32_t channel ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
chn.dwFlags |= OpenMPT::CHN_NOTEFADE;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_channel_panning( int32_t channel, double panning ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
chn.nPan = mpt::saturate_round<int32_t>( std::clamp( panning, -1.0, 1.0 ) * 128.0 + 128.0 );
|
||||
}
|
||||
|
||||
double module_ext_impl::get_channel_panning( int32_t channel ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
return ( chn.nPan - 128 ) / 128.0;
|
||||
}
|
||||
|
||||
void module_ext_impl::set_note_finetune( int32_t channel, double finetune ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
chn.microTuning = mpt::saturate_round<int16_t>( finetune * 32768.0 );
|
||||
}
|
||||
|
||||
double module_ext_impl::get_note_finetune( int32_t channel ) {
|
||||
if ( channel < 0 || channel >= OpenMPT::MAX_CHANNELS ) {
|
||||
throw openmpt::exception( "invalid channel" );
|
||||
}
|
||||
auto & chn = m_sndFile->m_PlayState.Chn[channel];
|
||||
return chn.microTuning / 32768.0;
|
||||
}
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
} // namespace openmpt
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* libopenmpt_ext_impl.hpp
|
||||
* -----------------------
|
||||
* Purpose: libopenmpt extensions - implementation header
|
||||
* Notes :
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_EXT_IMPL_HPP
|
||||
#define LIBOPENMPT_EXT_IMPL_HPP
|
||||
|
||||
#include "libopenmpt_internal.h"
|
||||
#include "libopenmpt_impl.hpp"
|
||||
#include "libopenmpt_ext.hpp"
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
class module_ext_impl
|
||||
: public module_impl
|
||||
, public ext::pattern_vis
|
||||
, public ext::interactive
|
||||
, public ext::interactive2
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
{
|
||||
public:
|
||||
module_ext_impl( callback_stream_wrapper stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( std::istream & stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const std::vector<std::byte> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const std::vector<std::uint8_t> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const std::vector<char> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const std::byte * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const char * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_ext_impl( const void * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void ctor();
|
||||
|
||||
public:
|
||||
|
||||
~module_ext_impl();
|
||||
|
||||
public:
|
||||
|
||||
void * get_interface( const std::string & interface_id );
|
||||
|
||||
// pattern_vis
|
||||
|
||||
effect_type get_pattern_row_channel_volume_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const override;
|
||||
|
||||
effect_type get_pattern_row_channel_effect_type( std::int32_t pattern, std::int32_t row, std::int32_t channel ) const override;
|
||||
|
||||
// interactive
|
||||
|
||||
void set_current_speed( std::int32_t speed ) override;
|
||||
|
||||
void set_current_tempo( std::int32_t tempo ) override;
|
||||
|
||||
void set_tempo_factor( double factor ) override;
|
||||
|
||||
double get_tempo_factor( ) const override;
|
||||
|
||||
void set_pitch_factor( double factor ) override;
|
||||
|
||||
double get_pitch_factor( ) const override;
|
||||
|
||||
void set_global_volume( double volume ) override;
|
||||
|
||||
double get_global_volume( ) const override;
|
||||
|
||||
void set_channel_volume( std::int32_t channel, double volume ) override;
|
||||
|
||||
double get_channel_volume( std::int32_t channel ) const override;
|
||||
|
||||
void set_channel_mute_status( std::int32_t channel, bool mute ) override;
|
||||
|
||||
bool get_channel_mute_status( std::int32_t channel ) const override;
|
||||
|
||||
void set_instrument_mute_status( std::int32_t instrument, bool mute ) override;
|
||||
|
||||
bool get_instrument_mute_status( std::int32_t instrument ) const override;
|
||||
|
||||
std::int32_t play_note( std::int32_t instrument, std::int32_t note, double volume, double panning ) override;
|
||||
|
||||
void stop_note( std::int32_t channel ) override;
|
||||
|
||||
void note_off( std::int32_t channel ) override;
|
||||
|
||||
void note_fade( std::int32_t channel ) override;
|
||||
|
||||
void set_channel_panning( std::int32_t channel, double panning ) override;
|
||||
|
||||
double get_channel_panning( std::int32_t channel ) override;
|
||||
|
||||
void set_note_finetune( std::int32_t channel, double finetune ) override;
|
||||
|
||||
double get_note_finetune( std::int32_t channel ) override;
|
||||
|
||||
/* add stuff here */
|
||||
|
||||
}; // class module_ext_impl
|
||||
|
||||
} // namespace openmpt
|
||||
|
||||
#endif // LIBOPENMPT_EXT_IMPL_HPP
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* libopenmpt_impl.hpp
|
||||
* -------------------
|
||||
* Purpose: libopenmpt private interface
|
||||
* Notes : This is not a public header. Do NOT ship in distributions dev packages.
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_IMPL_HPP
|
||||
#define LIBOPENMPT_IMPL_HPP
|
||||
|
||||
#include "libopenmpt_internal.h"
|
||||
#include "libopenmpt.hpp"
|
||||
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
// forward declarations
|
||||
namespace mpt {
|
||||
inline namespace mpt_libopenmpt {
|
||||
namespace IO {
|
||||
class FileCursorTraitsFileData;
|
||||
template <typename Tpath>
|
||||
class FileCursorFilenameTraits;
|
||||
template <typename Ttraits, typename Tfilenametraits>
|
||||
class FileCursor;
|
||||
} // namespace IO
|
||||
} // namespace mpt_libopenmpt
|
||||
} // namespace mpt
|
||||
namespace OpenMPT {
|
||||
namespace detail {
|
||||
template <typename Ttraits, typename Tfilenametraits>
|
||||
using FileCursor = mpt::IO::FileCursor<Ttraits, Tfilenametraits>;
|
||||
} // namespace detail
|
||||
namespace mpt {
|
||||
class PathString;
|
||||
} // namespace mpt
|
||||
using FileCursor = detail::FileCursor<mpt::IO::FileCursorTraitsFileData, mpt::IO::FileCursorFilenameTraits<mpt::PathString>>;
|
||||
class CSoundFile;
|
||||
struct DithersWrapperOpenMPT;
|
||||
} // namespace OpenMPT
|
||||
|
||||
namespace openmpt {
|
||||
|
||||
namespace version {
|
||||
|
||||
std::uint32_t get_library_version();
|
||||
std::uint32_t get_core_version();
|
||||
std::string get_string( const std::string & key );
|
||||
|
||||
} // namespace version
|
||||
|
||||
class log_interface {
|
||||
protected:
|
||||
log_interface();
|
||||
public:
|
||||
virtual ~log_interface();
|
||||
virtual void log( const std::string & message ) const = 0;
|
||||
}; // class log_interface
|
||||
|
||||
class std_ostream_log : public log_interface {
|
||||
private:
|
||||
std::ostream & destination;
|
||||
public:
|
||||
std_ostream_log( std::ostream & dst );
|
||||
virtual ~std_ostream_log();
|
||||
void log( const std::string & message ) const override;
|
||||
}; // class CSoundFileLog_std_ostream
|
||||
|
||||
class log_forwarder;
|
||||
|
||||
struct callback_stream_wrapper {
|
||||
void * stream;
|
||||
std::size_t (*read)( void * stream, void * dst, std::size_t bytes );
|
||||
int (*seek)( void * stream, std::int64_t offset, int whence );
|
||||
std::int64_t (*tell)( void * stream );
|
||||
}; // struct callback_stream_wrapper
|
||||
|
||||
class module_impl {
|
||||
public:
|
||||
enum class amiga_filter_type {
|
||||
a500,
|
||||
a1200,
|
||||
unfiltered,
|
||||
auto_filter,
|
||||
};
|
||||
|
||||
protected:
|
||||
struct subsong_data {
|
||||
double duration;
|
||||
std::int32_t start_row;
|
||||
std::int32_t start_order;
|
||||
std::int32_t sequence;
|
||||
subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence );
|
||||
}; // struct subsong_data
|
||||
|
||||
typedef std::vector<subsong_data> subsongs_type;
|
||||
|
||||
enum class song_end_action {
|
||||
fadeout_song,
|
||||
continue_song,
|
||||
stop_song,
|
||||
};
|
||||
|
||||
static constexpr std::int32_t all_subsongs = -1;
|
||||
|
||||
enum class ctl_type {
|
||||
boolean,
|
||||
integer,
|
||||
floatingpoint,
|
||||
text,
|
||||
};
|
||||
struct ctl_info {
|
||||
const char * name;
|
||||
ctl_type type;
|
||||
};
|
||||
|
||||
std::unique_ptr<log_interface> m_Log;
|
||||
std::unique_ptr<log_forwarder> m_LogForwarder;
|
||||
std::int32_t m_current_subsong;
|
||||
double m_currentPositionSeconds;
|
||||
std::unique_ptr<OpenMPT::CSoundFile> m_sndFile;
|
||||
bool m_loaded;
|
||||
bool m_mixer_initialized;
|
||||
std::unique_ptr<OpenMPT::DithersWrapperOpenMPT> m_Dithers;
|
||||
subsongs_type m_subsongs;
|
||||
float m_Gain;
|
||||
song_end_action m_ctl_play_at_end;
|
||||
amiga_filter_type m_ctl_render_resampler_emulate_amiga_type = amiga_filter_type::auto_filter;
|
||||
bool m_ctl_load_skip_samples;
|
||||
bool m_ctl_load_skip_patterns;
|
||||
bool m_ctl_load_skip_plugins;
|
||||
bool m_ctl_load_skip_subsongs_init;
|
||||
bool m_ctl_seek_sync_samples;
|
||||
std::vector<std::string> m_loaderMessages;
|
||||
public:
|
||||
void PushToCSoundFileLog( const std::string & text ) const;
|
||||
void PushToCSoundFileLog( int loglevel, const std::string & text ) const;
|
||||
protected:
|
||||
std::string mod_string_to_utf8( const std::string & encoded ) const;
|
||||
void apply_mixer_settings( std::int32_t samplerate, int channels );
|
||||
void apply_libopenmpt_defaults();
|
||||
subsongs_type get_subsongs() const;
|
||||
void init_subsongs( subsongs_type & subsongs ) const;
|
||||
bool has_subsongs_inited() const;
|
||||
void ctor( const std::map< std::string, std::string > & ctls );
|
||||
void load( const OpenMPT::FileCursor & file, const std::map< std::string, std::string > & ctls );
|
||||
bool is_loaded() const;
|
||||
std::size_t read_wrapper( std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right );
|
||||
std::size_t read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right );
|
||||
std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved );
|
||||
std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved );
|
||||
std::string get_message_instruments() const;
|
||||
std::string get_message_samples() const;
|
||||
std::pair< std::string, std::string > format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int command ) const;
|
||||
std::pair< std::string, std::string > format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
|
||||
static double could_open_probability( const OpenMPT::FileCursor & file, double effort, std::unique_ptr<log_interface> log );
|
||||
public:
|
||||
static std::vector<std::string> get_supported_extensions();
|
||||
|
||||
/// <summary>
|
||||
/// From version 0.7.0
|
||||
/// Hakan DANISIK
|
||||
/// </summary>
|
||||
/// <param name="extension"></param>
|
||||
/// <returns></returns>
|
||||
static std::string get_tracker_name( const std::string & extension );
|
||||
|
||||
static bool is_extension_supported( std::string_view extension );
|
||||
static double could_open_probability( callback_stream_wrapper stream, double effort, std::unique_ptr<log_interface> log );
|
||||
static double could_open_probability( std::istream & stream, double effort, std::unique_ptr<log_interface> log );
|
||||
static std::size_t probe_file_header_get_recommended_size();
|
||||
static int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size, std::uint64_t filesize );
|
||||
static int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size, std::uint64_t filesize );
|
||||
static int probe_file_header( std::uint64_t flags, const void * data, std::size_t size, std::uint64_t filesize );
|
||||
static int probe_file_header( std::uint64_t flags, const std::byte * data, std::size_t size );
|
||||
static int probe_file_header( std::uint64_t flags, const std::uint8_t * data, std::size_t size );
|
||||
static int probe_file_header( std::uint64_t flags, const void * data, std::size_t size );
|
||||
static int probe_file_header( std::uint64_t flags, std::istream & stream );
|
||||
static int probe_file_header( std::uint64_t flags, callback_stream_wrapper stream );
|
||||
module_impl( callback_stream_wrapper stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( std::istream & stream, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const std::vector<std::byte> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const std::vector<std::uint8_t> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const std::vector<char> & data, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const std::byte * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const std::uint8_t * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const char * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
module_impl( const void * data, std::size_t size, std::unique_ptr<log_interface> log, const std::map< std::string, std::string > & ctls );
|
||||
~module_impl();
|
||||
public:
|
||||
void select_subsong( std::int32_t subsong );
|
||||
std::int32_t get_selected_subsong() const;
|
||||
void set_repeat_count( std::int32_t repeat_count );
|
||||
std::int32_t get_repeat_count() const;
|
||||
double get_duration_seconds() const;
|
||||
double set_position_seconds( double seconds );
|
||||
double get_position_seconds() const;
|
||||
double set_position_order_row( std::int32_t order, std::int32_t row );
|
||||
std::int32_t get_render_param( int param ) const;
|
||||
void set_render_param( int param, std::int32_t value );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * mono );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, std::int16_t * left, std::int16_t * right, std::int16_t * rear_left, std::int16_t * rear_right );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, float * mono );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right );
|
||||
std::size_t read( std::int32_t samplerate, std::size_t count, float * left, float * right, float * rear_left, float * rear_right );
|
||||
std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_stereo );
|
||||
std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, std::int16_t * interleaved_quad );
|
||||
std::size_t read_interleaved_stereo( std::int32_t samplerate, std::size_t count, float * interleaved_stereo );
|
||||
std::size_t read_interleaved_quad( std::int32_t samplerate, std::size_t count, float * interleaved_quad );
|
||||
std::vector<std::string> get_metadata_keys() const;
|
||||
std::string get_metadata( const std::string & key ) const;
|
||||
double get_current_estimated_bpm() const;
|
||||
std::int32_t get_current_speed() const;
|
||||
std::int32_t get_current_tempo() const;
|
||||
std::int32_t get_current_order() const;
|
||||
std::int32_t get_current_pattern() const;
|
||||
std::int32_t get_current_row() const;
|
||||
std::int32_t get_current_playing_channels() const;
|
||||
float get_current_channel_vu_mono( std::int32_t channel ) const;
|
||||
float get_current_channel_vu_left( std::int32_t channel ) const;
|
||||
float get_current_channel_vu_right( std::int32_t channel ) const;
|
||||
float get_current_channel_vu_rear_left( std::int32_t channel ) const;
|
||||
float get_current_channel_vu_rear_right( std::int32_t channel ) const;
|
||||
std::int32_t get_num_subsongs() const;
|
||||
std::int32_t get_num_channels() const;
|
||||
std::int32_t get_num_orders() const;
|
||||
std::int32_t get_num_patterns() const;
|
||||
std::int32_t get_num_instruments() const;
|
||||
std::int32_t get_num_samples() const;
|
||||
std::vector<std::string> get_subsong_names() const;
|
||||
std::vector<std::string> get_channel_names() const;
|
||||
std::vector<std::string> get_order_names() const;
|
||||
std::vector<std::string> get_pattern_names() const;
|
||||
std::vector<std::string> get_instrument_names() const;
|
||||
std::vector<std::string> get_sample_names() const;
|
||||
std::int32_t get_order_pattern( std::int32_t o ) const;
|
||||
std::int32_t get_pattern_num_rows( std::int32_t p ) const;
|
||||
std::uint8_t get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
|
||||
std::string format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
|
||||
std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
|
||||
std::string format_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
|
||||
std::string highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
|
||||
std::pair<const module_impl::ctl_info *, const module_impl::ctl_info *> get_ctl_infos() const;
|
||||
std::vector<std::string> get_ctls() const;
|
||||
std::string ctl_get( std::string ctl, bool throw_if_unknown = true ) const;
|
||||
bool ctl_get_boolean( std::string_view ctl, bool throw_if_unknown = true ) const;
|
||||
std::int64_t ctl_get_integer( std::string_view ctl, bool throw_if_unknown = true ) const;
|
||||
double ctl_get_floatingpoint( std::string_view ctl, bool throw_if_unknown = true ) const;
|
||||
std::string ctl_get_text( std::string_view ctl, bool throw_if_unknown = true ) const;
|
||||
void ctl_set( std::string ctl, const std::string & value, bool throw_if_unknown = true );
|
||||
void ctl_set_boolean( std::string_view ctl, bool value, bool throw_if_unknown = true );
|
||||
void ctl_set_integer( std::string_view ctl, std::int64_t value, bool throw_if_unknown = true );
|
||||
void ctl_set_floatingpoint( std::string_view ctl, double value, bool throw_if_unknown = true );
|
||||
void ctl_set_text( std::string_view ctl, std::string_view value, bool throw_if_unknown = true );
|
||||
}; // class module_impl
|
||||
|
||||
namespace helper {
|
||||
|
||||
template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
} // namespace helper
|
||||
|
||||
} // namespace openmpt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // LIBOPENMPT_IMPL_HPP
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* libopenmpt_internal.h
|
||||
* ---------------------
|
||||
* Purpose: libopenmpt internal interface configuration, overruling the public interface configuration (only used and needed when building libopenmpt)
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_INTERNAL_H
|
||||
#define LIBOPENMPT_INTERNAL_H
|
||||
|
||||
#include "libopenmpt_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(LIBOPENMPT_BUILD_DLL) || defined(LIBOPENMPT_USE_DLL)
|
||||
#if defined(_MSC_VER) && !defined(_DLL)
|
||||
/* #pragma message( "libopenmpt C++ interface is disabled if libopenmpt is built as a DLL and the runtime is statically linked. This is not supported by microsoft and cannot possibly work. Ever." ) */
|
||||
#undef LIBOPENMPT_CXX_API
|
||||
#define LIBOPENMPT_CXX_API LIBOPENMPT_API_HELPER_LOCAL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* LIBOPENMPT_INTERNAL_H */
|
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
* libopenmpt_plugin_gui.cpp
|
||||
* -------------------------
|
||||
* Purpose: libopenmpt plugin GUI
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#if !defined(WINVER) && !defined(_WIN32_WINDOWS)
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 // _WIN32_WINNT_WINXP
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MPT_BUILD_RETRO)
|
||||
#if defined(_MSC_VER)
|
||||
#define MPT_WITH_MFC
|
||||
#endif
|
||||
#else
|
||||
#if defined(_WIN32_WINNT)
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
#if defined(_MSC_VER)
|
||||
#define MPT_WITH_MFC
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MPT_WITH_MFC)
|
||||
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS // Avoid binary bloat from linking unused MFC controls
|
||||
#endif // MPT_WITH_MFC
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#if !defined(MPT_WITH_MFC)
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#if !defined(MPT_WITH_MFC)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
#include <afxwin.h>
|
||||
#include <afxcmn.h>
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
#include "resource.h"
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
#include "libopenmpt_plugin_gui.hpp"
|
||||
|
||||
|
||||
namespace libopenmpt {
|
||||
namespace plugin {
|
||||
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
|
||||
|
||||
class CSettingsApp : public CWinApp {
|
||||
|
||||
public:
|
||||
|
||||
BOOL InitInstance() override {
|
||||
if ( !CWinApp::InitInstance() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DllMainAttach();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int ExitInstance() override {
|
||||
DllMainDetach();
|
||||
return CWinApp::ExitInstance();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
CSettingsApp theApp;
|
||||
|
||||
|
||||
class CSettingsDialog : public CDialog {
|
||||
|
||||
protected:
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
libopenmpt_settings * s;
|
||||
|
||||
CString m_Title;
|
||||
|
||||
CComboBox m_ComboBoxSamplerate;
|
||||
CComboBox m_ComboBoxChannels;
|
||||
CSliderCtrl m_SliderCtrlGain;
|
||||
CComboBox m_ComboBoxInterpolation;
|
||||
CButton m_CheckBoxAmigaResampler;
|
||||
CComboBox m_ComboBoxAmigaFilter;
|
||||
CComboBox m_ComboBoxRepeat;
|
||||
CSliderCtrl m_SliderCtrlStereoSeparation;
|
||||
CComboBox m_ComboBoxRamping;
|
||||
|
||||
public:
|
||||
|
||||
CSettingsDialog( libopenmpt_settings * s_, CString title, CWnd * parent = nullptr )
|
||||
: CDialog( IDD_SETTINGS, parent )
|
||||
, s( s_ )
|
||||
, m_Title( title )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void DoDataExchange( CDataExchange * pDX ) override
|
||||
{
|
||||
CDialog::DoDataExchange( pDX );
|
||||
DDX_Control( pDX, IDC_COMBO_SAMPLERATE, m_ComboBoxSamplerate );
|
||||
DDX_Control( pDX, IDC_COMBO_CHANNELS, m_ComboBoxChannels );
|
||||
DDX_Control( pDX, IDC_SLIDER_GAIN, m_SliderCtrlGain );
|
||||
DDX_Control( pDX, IDC_COMBO_INTERPOLATION, m_ComboBoxInterpolation );
|
||||
DDX_Control( pDX, IDC_CHECK_AMIGA_RESAMPLER, m_CheckBoxAmigaResampler );
|
||||
DDX_Control( pDX, IDC_COMBO_AMIGA_FILTER, m_ComboBoxAmigaFilter );
|
||||
DDX_Control( pDX, IDC_COMBO_REPEAT, m_ComboBoxRepeat );
|
||||
DDX_Control( pDX, IDC_SLIDER_STEREOSEPARATION, m_SliderCtrlStereoSeparation );
|
||||
DDX_Control( pDX, IDC_COMBO_RAMPING, m_ComboBoxRamping );
|
||||
}
|
||||
|
||||
afx_msg BOOL OnInitDialog() override {
|
||||
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
SetWindowText( m_Title );
|
||||
EnableToolTips();
|
||||
|
||||
bool selected = false;
|
||||
|
||||
selected = false;
|
||||
if ( !s->no_default_format ) {
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"Default" ), 0 );
|
||||
}
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"6000" ), 6000 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"8000" ), 8000 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"11025" ), 11025 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"16000" ), 16000 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"22050" ), 22050 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"32000" ), 32000 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"44100" ), 44100 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"48000" ), 48000 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"88200" ), 88200 );
|
||||
m_ComboBoxSamplerate.SetItemData( m_ComboBoxSamplerate.AddString( L"96000" ), 96000 );
|
||||
if ( !s->no_default_format && s->samplerate == 0 ) {
|
||||
m_ComboBoxSamplerate.SelectString( 0, L"Default" );
|
||||
}
|
||||
for ( int index = 0; index < m_ComboBoxSamplerate.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxSamplerate.GetItemData( index ) ) == s->samplerate ) {
|
||||
m_ComboBoxSamplerate.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxSamplerate.SelectString( 0, L"48000" );
|
||||
}
|
||||
|
||||
selected = false;
|
||||
if ( !s->no_default_format ) {
|
||||
m_ComboBoxChannels.SetItemData( m_ComboBoxChannels.AddString( L"Default" ), 0 );
|
||||
}
|
||||
m_ComboBoxChannels.SetItemData( m_ComboBoxChannels.AddString( L"Mono" ), 1 );
|
||||
m_ComboBoxChannels.SetItemData( m_ComboBoxChannels.AddString( L"Stereo" ), 2 );
|
||||
m_ComboBoxChannels.SetItemData( m_ComboBoxChannels.AddString( L"Quad" ), 4 );
|
||||
if ( !s->no_default_format && s->channels == 0 ) {
|
||||
m_ComboBoxChannels.SelectString( 0, L"Default" );
|
||||
}
|
||||
for ( int index = 0; index < m_ComboBoxChannels.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxChannels.GetItemData( index ) ) == s->channels ) {
|
||||
m_ComboBoxChannels.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxChannels.SelectString( 0, L"Stereo" );
|
||||
}
|
||||
|
||||
m_SliderCtrlGain.SetRange( -1200, 1200 );
|
||||
m_SliderCtrlGain.SetTicFreq( 100 );
|
||||
m_SliderCtrlGain.SetPageSize( 300 );
|
||||
m_SliderCtrlGain.SetLineSize( 100 );
|
||||
m_SliderCtrlGain.SetPos( s->mastergain_millibel );
|
||||
|
||||
selected = false;
|
||||
m_ComboBoxInterpolation.SetItemData( m_ComboBoxInterpolation.AddString( L"Off / 1 Tap (Nearest)" ), 1 );
|
||||
m_ComboBoxInterpolation.SetItemData( m_ComboBoxInterpolation.AddString( L"2 Tap (Linear)" ), 2 );
|
||||
m_ComboBoxInterpolation.SetItemData( m_ComboBoxInterpolation.AddString( L"4 Tap (Cubic)" ), 4 );
|
||||
m_ComboBoxInterpolation.SetItemData( m_ComboBoxInterpolation.AddString( L"8 Tap (Polyphase FIR)" ), 8 );
|
||||
for ( int index = 0; index < m_ComboBoxInterpolation.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxInterpolation.GetItemData( index ) ) == s->interpolationfilterlength ) {
|
||||
m_ComboBoxInterpolation.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxInterpolation.SelectString( 0, L"8 Tap (Polyphase FIR)" );
|
||||
}
|
||||
|
||||
m_CheckBoxAmigaResampler.SetCheck( s->use_amiga_resampler ? BST_CHECKED : BST_UNCHECKED );
|
||||
selected = false;
|
||||
m_ComboBoxAmigaFilter.EnableWindow( s->use_amiga_resampler ? TRUE : FALSE );
|
||||
m_ComboBoxAmigaFilter.SetItemData( m_ComboBoxAmigaFilter.AddString( L"Default" ), 0 );
|
||||
m_ComboBoxAmigaFilter.SetItemData( m_ComboBoxAmigaFilter.AddString( L"A500 Filter" ), 0xA500 );
|
||||
m_ComboBoxAmigaFilter.SetItemData( m_ComboBoxAmigaFilter.AddString( L"A1200 Filter" ), 0xA1200 );
|
||||
m_ComboBoxAmigaFilter.SetItemData( m_ComboBoxAmigaFilter.AddString( L"Unfiltered" ), 1 );
|
||||
for ( int index = 0; index < m_ComboBoxAmigaFilter.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxAmigaFilter.GetItemData( index ) ) == s->amiga_filter_type ) {
|
||||
m_ComboBoxAmigaFilter.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxAmigaFilter.SelectString( 0, L"Default" );
|
||||
}
|
||||
|
||||
selected = false;
|
||||
m_ComboBoxRepeat.SetItemData( m_ComboBoxRepeat.AddString( L"Forever" ), static_cast<unsigned int>( -1 ) );
|
||||
m_ComboBoxRepeat.SetItemData( m_ComboBoxRepeat.AddString( L"Never" ), 0 );
|
||||
m_ComboBoxRepeat.SetItemData( m_ComboBoxRepeat.AddString( L"Once" ), 1 );
|
||||
for ( int index = 0; index < m_ComboBoxRepeat.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxRepeat.GetItemData( index ) ) == s->repeatcount ) {
|
||||
m_ComboBoxRepeat.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxRepeat.SelectString( 0, L"Never" );
|
||||
}
|
||||
|
||||
m_SliderCtrlStereoSeparation.SetRange( 0, 200 );
|
||||
m_SliderCtrlStereoSeparation.SetTicFreq( 100 );
|
||||
m_SliderCtrlStereoSeparation.SetPageSize( 25 );
|
||||
m_SliderCtrlStereoSeparation.SetLineSize( 5 );
|
||||
m_SliderCtrlStereoSeparation.SetPos( s->stereoseparation );
|
||||
|
||||
selected = false;
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"Default" ), static_cast<unsigned int>( -1 ) );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"Off" ), 0 );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"1 ms" ), 1 );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"2 ms" ), 2 );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"3 ms" ), 3 );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"5 ms" ), 5 );
|
||||
m_ComboBoxRamping.SetItemData( m_ComboBoxRamping.AddString( L"10 ms" ), 10 );
|
||||
for ( int index = 0; index < m_ComboBoxRamping.GetCount(); ++index ) {
|
||||
if ( static_cast<int>( m_ComboBoxRamping.GetItemData( index ) ) == s->ramping ) {
|
||||
m_ComboBoxRamping.SetCurSel( index );
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if ( !selected ) {
|
||||
m_ComboBoxRamping.SelectString( 0, L"Default" );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
void OnOK() override {
|
||||
|
||||
s->samplerate = m_ComboBoxSamplerate.GetItemData( m_ComboBoxSamplerate.GetCurSel() );
|
||||
|
||||
s->channels = m_ComboBoxChannels.GetItemData( m_ComboBoxChannels.GetCurSel() );
|
||||
|
||||
s->mastergain_millibel = m_SliderCtrlGain.GetPos();
|
||||
|
||||
s->interpolationfilterlength = m_ComboBoxInterpolation.GetItemData( m_ComboBoxInterpolation.GetCurSel() );
|
||||
|
||||
s->use_amiga_resampler = ( m_CheckBoxAmigaResampler.GetCheck() != BST_UNCHECKED ) ? 1 : 0;
|
||||
s->amiga_filter_type = m_ComboBoxAmigaFilter.GetItemData( m_ComboBoxAmigaFilter.GetCurSel() );
|
||||
|
||||
s->repeatcount = m_ComboBoxRepeat.GetItemData( m_ComboBoxRepeat.GetCurSel() );
|
||||
|
||||
s->stereoseparation = m_SliderCtrlStereoSeparation.GetPos();
|
||||
|
||||
s->ramping = m_ComboBoxRamping.GetItemData( m_ComboBoxRamping.GetCurSel() );
|
||||
|
||||
s->changed();
|
||||
|
||||
CDialog::OnOK();
|
||||
|
||||
}
|
||||
|
||||
BOOL OnToolTipText( UINT, NMHDR * pNMHDR, LRESULT * pResult ) {
|
||||
TOOLTIPTEXT * pTTT = reinterpret_cast<TOOLTIPTEXT *>( pNMHDR );
|
||||
|
||||
UINT_PTR nID = pNMHDR->idFrom;
|
||||
if( pTTT->uFlags & TTF_IDISHWND )
|
||||
{
|
||||
// idFrom is actually the HWND of the tool
|
||||
nID = (UINT_PTR)::GetDlgCtrlID((HWND)nID);
|
||||
}
|
||||
|
||||
switch ( nID ) {
|
||||
case IDC_SLIDER_GAIN:
|
||||
swprintf( pTTT->szText, _countof(pTTT->szText), L"%.02f dB", m_SliderCtrlGain.GetPos() * 0.01f );
|
||||
break;
|
||||
|
||||
case IDC_SLIDER_STEREOSEPARATION:
|
||||
swprintf( pTTT->szText, _countof(pTTT->szText), L"%d %%", m_SliderCtrlStereoSeparation.GetPos());
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void OnAmigaResamplerChanged() {
|
||||
m_ComboBoxAmigaFilter.EnableWindow( IsDlgButtonChecked( IDC_CHECK_AMIGA_RESAMPLER ) != BST_UNCHECKED ? TRUE : FALSE );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSettingsDialog, CDialog)
|
||||
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, &CSettingsDialog::OnToolTipText)
|
||||
ON_COMMAND( IDC_CHECK_AMIGA_RESAMPLER, &CSettingsDialog::OnAmigaResamplerChanged )
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
||||
class CInfoDialog : public CDialog {
|
||||
|
||||
protected:
|
||||
|
||||
CString m_Title;
|
||||
CString m_FileInfo;
|
||||
CEdit m_EditFileInfo;
|
||||
|
||||
public:
|
||||
|
||||
CInfoDialog( CString title, CString info, CWnd * parent = NULL )
|
||||
: CDialog( IDD_FILEINFO, parent )
|
||||
, m_Title( title )
|
||||
, m_FileInfo( info )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void DoDataExchange( CDataExchange * pDX ) override
|
||||
{
|
||||
CDialog::DoDataExchange( pDX );
|
||||
DDX_Control( pDX, IDC_FILEINFO, m_EditFileInfo );
|
||||
}
|
||||
|
||||
afx_msg BOOL OnInitDialog() override {
|
||||
|
||||
if ( !CDialog::OnInitDialog() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetWindowText( m_Title );
|
||||
|
||||
m_EditFileInfo.SetWindowText( m_FileInfo );
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
|
||||
void gui_edit_settings( libopenmpt_settings * s, HWND parent, std::wstring title ) {
|
||||
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
|
||||
CSettingsDialog dlg( s, title.c_str(), parent ? CWnd::FromHandle( parent ) : nullptr );
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
|
||||
void gui_show_file_info( HWND parent, std::wstring title, std::wstring info ) {
|
||||
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
|
||||
CInfoDialog dlg( title.c_str(), info.c_str(), parent ? CWnd::FromHandle( parent ) : nullptr);
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
|
||||
#else // !MPT_WITH_MFC
|
||||
|
||||
|
||||
static std::basic_string<TCHAR> GetTempDirectory() {
|
||||
DWORD size = GetTempPath(0, nullptr);
|
||||
if (size) {
|
||||
std::vector<TCHAR> tempPath(size + 1);
|
||||
if (GetTempPath(size + 1, tempPath.data())) {
|
||||
return tempPath.data();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static std::basic_string<TCHAR> GetTempFilename( std::basic_string<TCHAR> prefix ) {
|
||||
std::vector<TCHAR> buf(MAX_PATH);
|
||||
if (GetTempFileName(GetTempDirectory().c_str(), prefix.c_str(), 0, buf.data()) == 0) {
|
||||
return {};
|
||||
}
|
||||
return buf.data();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::basic_string<TCHAR> as_string( T x ) {
|
||||
std::basic_ostringstream<TCHAR> s;
|
||||
s.imbue(std::locale::classic());
|
||||
s << x;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
void gui_edit_settings( libopenmpt_settings * s, HWND /* parent */ , std::basic_string<TCHAR> title ) {
|
||||
std::basic_string<TCHAR> filename = GetTempFilename( title );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("Samplerate_Hz"), as_string( s->samplerate ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("Channels"), as_string( s->channels ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("MasterGain_milliBel"), as_string( s->mastergain_millibel ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("StereoSeparation_Percent"), as_string( s->stereoseparation ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("RepeatCount"), as_string( s->repeatcount ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("InterpolationFilterLength"), as_string( s->interpolationfilterlength ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("UseAmigaResampler"), as_string( s->use_amiga_resampler ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("AmigaFilterType"), as_string( s->amiga_filter_type ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("VolumeRampingStrength"), as_string( s->ramping ).c_str(), filename.c_str() );
|
||||
WritePrivateProfileString( title.c_str(), TEXT("VisAllowScroll"), as_string( s->vis_allow_scroll ).c_str(), filename.c_str() );
|
||||
STARTUPINFO startupInfo = {};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
PROCESS_INFORMATION processInformation = {};
|
||||
std::basic_string<TCHAR> command = std::basic_string<TCHAR>(TEXT("notepad.exe")) + TEXT(" ") + filename;
|
||||
std::vector<TCHAR> commandBuf{ command.c_str(), command.c_str() + command.length() + 1 };
|
||||
if ( CreateProcess( NULL, commandBuf.data(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation ) == FALSE ) {
|
||||
MessageBox(NULL, as_string(GetLastError()).c_str(), TEXT("fail"), 0);
|
||||
return;
|
||||
}
|
||||
CloseHandle( processInformation.hThread );
|
||||
WaitForSingleObject( processInformation.hProcess, INFINITE );
|
||||
CloseHandle( processInformation.hProcess );
|
||||
s->samplerate = GetPrivateProfileInt( title.c_str(), TEXT("Samplerate_Hz"), libopenmpt_settings{}.samplerate, filename.c_str() );
|
||||
s->channels = GetPrivateProfileInt( title.c_str(), TEXT("Channels"), libopenmpt_settings{}.channels, filename.c_str() );
|
||||
s->mastergain_millibel = GetPrivateProfileInt( title.c_str(), TEXT("MasterGain_milliBel"), libopenmpt_settings{}.mastergain_millibel, filename.c_str() );
|
||||
s->stereoseparation = GetPrivateProfileInt( title.c_str(), TEXT("StereoSeparation_Percent"), libopenmpt_settings{}.stereoseparation, filename.c_str() );
|
||||
s->repeatcount = GetPrivateProfileInt( title.c_str(), TEXT("RepeatCount"), libopenmpt_settings{}.repeatcount, filename.c_str() );
|
||||
s->interpolationfilterlength = GetPrivateProfileInt( title.c_str(), TEXT("InterpolationFilterLength"), libopenmpt_settings{}.interpolationfilterlength, filename.c_str() );
|
||||
s->use_amiga_resampler = GetPrivateProfileInt( title.c_str(), TEXT("UseAmigaResampler"), libopenmpt_settings{}.use_amiga_resampler, filename.c_str() );
|
||||
s->amiga_filter_type = GetPrivateProfileInt( title.c_str(), TEXT("AmigaFilterType"), libopenmpt_settings{}.amiga_filter_type, filename.c_str() );
|
||||
s->ramping = GetPrivateProfileInt( title.c_str(), TEXT("VolumeRampingStrength"), libopenmpt_settings{}.ramping, filename.c_str() );
|
||||
s->vis_allow_scroll = GetPrivateProfileInt( title.c_str(), TEXT("VisAllowScroll"), libopenmpt_settings{}.vis_allow_scroll, filename.c_str() );
|
||||
DeleteFile( filename.c_str() );
|
||||
}
|
||||
|
||||
|
||||
void gui_show_file_info( HWND /* parent */ , std::basic_string<TCHAR> title, std::basic_string<TCHAR> info ) {
|
||||
std::basic_string<TCHAR> filename = GetTempFilename( title );
|
||||
{
|
||||
std::basic_ofstream<TCHAR> f( filename.c_str(), std::ios::out );
|
||||
f << info;
|
||||
}
|
||||
STARTUPINFO startupInfo = {};
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
PROCESS_INFORMATION processInformation = {};
|
||||
std::basic_string<TCHAR> command = std::basic_string<TCHAR>(TEXT("notepad.exe")) + TEXT(" ") + filename;
|
||||
std::vector<TCHAR> commandBuf{ command.c_str(), command.c_str() + command.length() + 1 };
|
||||
if ( CreateProcess( NULL, commandBuf.data(), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation ) == FALSE ) {
|
||||
return;
|
||||
}
|
||||
CloseHandle( processInformation.hThread );
|
||||
WaitForSingleObject( processInformation.hProcess, INFINITE );
|
||||
CloseHandle( processInformation.hProcess );
|
||||
DeleteFile( filename.c_str() );
|
||||
}
|
||||
|
||||
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace libopenmpt
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* libopenmpt_plugin_gui.hpp
|
||||
* -------------------------
|
||||
* Purpose: libopenmpt plugin GUI
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_PLUGIN_GUI_HPP
|
||||
#define LIBOPENMPT_PLUGIN_GUI_HPP
|
||||
|
||||
#include "libopenmpt_plugin_settings.hpp"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libopenmpt {
|
||||
namespace plugin {
|
||||
|
||||
#if defined(MPT_WITH_MFC)
|
||||
|
||||
void DllMainAttach();
|
||||
void DllMainDetach();
|
||||
|
||||
#endif // MPT_WITH_MFC
|
||||
|
||||
void gui_edit_settings( libopenmpt_settings * s, HWND parent, std::basic_string<TCHAR> title );
|
||||
|
||||
void gui_show_file_info( HWND parent, std::basic_string<TCHAR> title, std::basic_string<TCHAR> info );
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace libopenmpt
|
||||
|
||||
#endif // LIBOPENMPT_PLUGIN_GUI_HPP
|
|
@ -0,0 +1,147 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// German (Germany) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
|
||||
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_SETTINGS DIALOGEX 0, 0, 201, 200
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&OK",IDOK,78,180,54,14
|
||||
PUSHBUTTON "&Cancel",IDCANCEL,138,180,54,14
|
||||
LTEXT "&Samplerate",IDC_STATIC,6,6,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_SAMPLERATE,72,6,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "C&hannels",IDC_STATIC,6,24,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_CHANNELS,72,24,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "&Gain",IDC_STATIC,6,42,60,12,SS_CENTERIMAGE
|
||||
CONTROL "",IDC_SLIDER_GAIN,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,72,42,120,15
|
||||
LTEXT "&Interpolation",IDC_STATIC,6,60,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_INTERPOLATION,72,60,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Use &Amiga resampler for Amiga modules",IDC_CHECK_AMIGA_RESAMPLER,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,78,186,12
|
||||
LTEXT "Amiga &Filter Type:",IDC_STATIC,6,96,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_AMIGA_FILTER,72,96,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "&Repeat",IDC_STATIC,6,114,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_REPEAT,72,114,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "S&tereo Separation",IDC_STATIC,6,132,60,12,SS_CENTERIMAGE
|
||||
CONTROL "",IDC_SLIDER_STEREOSEPARATION,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,72,132,126,15
|
||||
LTEXT "&Volume Ramping",IDC_STATIC,6,151,60,12,SS_CENTERIMAGE
|
||||
COMBOBOX IDC_COMBO_RAMPING,72,151,120,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,6,175,186,1
|
||||
END
|
||||
|
||||
IDD_FILEINFO DIALOGEX 0, 0, 310, 174
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,258,156,48,12
|
||||
EDITTEXT IDC_FILEINFO,6,6,300,144,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_SETTINGS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 194
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 193
|
||||
END
|
||||
|
||||
IDD_FILEINFO, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 303
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 167
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AFX_DIALOG_LAYOUT
|
||||
//
|
||||
|
||||
IDD_SETTINGS AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_FILEINFO AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0,
|
||||
100, 100, 0, 0,
|
||||
0, 0, 100, 100
|
||||
END
|
||||
|
||||
#endif // German (Germany) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* libopenmpt_plugin_settings.hpp
|
||||
* ------------------------------
|
||||
* Purpose: libopenmpt plugin settings
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_PLUGIN_SETTINGS_HPP
|
||||
#define LIBOPENMPT_PLUGIN_SETTINGS_HPP
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace libopenmpt {
|
||||
namespace plugin {
|
||||
|
||||
|
||||
typedef void (*changed_func)();
|
||||
|
||||
struct libopenmpt_settings {
|
||||
bool no_default_format = true;
|
||||
int samplerate = 48000;
|
||||
int channels = 2;
|
||||
int mastergain_millibel = 0;
|
||||
int stereoseparation = 100;
|
||||
int use_amiga_resampler = 0;
|
||||
int amiga_filter_type = 0;
|
||||
int repeatcount = 0;
|
||||
int interpolationfilterlength = 8;
|
||||
int ramping = -1;
|
||||
int vis_allow_scroll = 1;
|
||||
changed_func changed = nullptr;
|
||||
};
|
||||
|
||||
|
||||
class settings : public libopenmpt_settings {
|
||||
private:
|
||||
std::basic_string<TCHAR> subkey;
|
||||
protected:
|
||||
virtual void read_setting( const std::string & /* key */ , const std::basic_string<TCHAR> & key, int & val ) {
|
||||
HKEY regkey = HKEY();
|
||||
if ( RegOpenKeyEx( HKEY_CURRENT_USER, ( TEXT("Software\\libopenmpt\\") + subkey ).c_str(), 0, KEY_READ, ®key ) == ERROR_SUCCESS ) {
|
||||
DWORD v = val;
|
||||
DWORD type = REG_DWORD;
|
||||
DWORD typesize = sizeof(v);
|
||||
if ( RegQueryValueEx( regkey, key.c_str(), NULL, &type, (BYTE *)&v, &typesize ) == ERROR_SUCCESS )
|
||||
{
|
||||
val = v;
|
||||
}
|
||||
RegCloseKey( regkey );
|
||||
regkey = HKEY();
|
||||
}
|
||||
}
|
||||
virtual void write_setting( const std::string & /* key */, const std::basic_string<TCHAR> & key, int val ) {
|
||||
HKEY regkey = HKEY();
|
||||
if ( RegCreateKeyEx( HKEY_CURRENT_USER, ( TEXT("Software\\libopenmpt\\") + subkey ).c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, ®key, NULL ) == ERROR_SUCCESS ) {
|
||||
DWORD v = val;
|
||||
DWORD type = REG_DWORD;
|
||||
DWORD typesize = sizeof(v);
|
||||
if ( RegSetValueEx( regkey, key.c_str(), 0, type, (const BYTE *)&v, typesize ) == ERROR_SUCCESS )
|
||||
{
|
||||
// ok
|
||||
}
|
||||
RegCloseKey( regkey );
|
||||
regkey = HKEY();
|
||||
}
|
||||
}
|
||||
public:
|
||||
settings( const std::basic_string<TCHAR> & subkey, bool no_default_format_ )
|
||||
: subkey(subkey)
|
||||
{
|
||||
no_default_format = no_default_format_;
|
||||
}
|
||||
void load()
|
||||
{
|
||||
#ifdef UNICODE
|
||||
#define read_setting(a,b,c) read_setting( b , L ## b , c)
|
||||
#else
|
||||
#define read_setting(a,b,c) read_setting( b , b , c)
|
||||
#endif
|
||||
read_setting( subkey, "Samplerate_Hz", samplerate );
|
||||
read_setting( subkey, "Channels", channels );
|
||||
read_setting( subkey, "MasterGain_milliBel", mastergain_millibel );
|
||||
read_setting( subkey, "StereoSeparation_Percent", stereoseparation );
|
||||
read_setting( subkey, "RepeatCount", repeatcount );
|
||||
read_setting( subkey, "InterpolationFilterLength", interpolationfilterlength );
|
||||
read_setting( subkey, "UseAmigaResampler", use_amiga_resampler );
|
||||
read_setting( subkey, "AmigaFilterType", amiga_filter_type );
|
||||
read_setting( subkey, "VolumeRampingStrength", ramping );
|
||||
read_setting( subkey, "VisAllowScroll", vis_allow_scroll );
|
||||
#undef read_setting
|
||||
}
|
||||
void save()
|
||||
{
|
||||
#ifdef UNICODE
|
||||
#define write_setting(a,b,c) write_setting( b , L ## b , c)
|
||||
#else
|
||||
#define write_setting(a,b,c) write_setting( b , b , c)
|
||||
#endif
|
||||
write_setting( subkey, "Samplerate_Hz", samplerate );
|
||||
write_setting( subkey, "Channels", channels );
|
||||
write_setting( subkey, "MasterGain_milliBel", mastergain_millibel );
|
||||
write_setting( subkey, "StereoSeparation_Percent", stereoseparation );
|
||||
write_setting( subkey, "RepeatCount", repeatcount );
|
||||
write_setting( subkey, "InterpolationFilterLength", interpolationfilterlength );
|
||||
write_setting( subkey, "UseAmigaResampler", use_amiga_resampler );
|
||||
write_setting( subkey, "AmigaFilterType", amiga_filter_type );
|
||||
write_setting( subkey, "VolumeRampingStrength", ramping );
|
||||
write_setting( subkey, "VisAllowScroll", vis_allow_scroll );
|
||||
#undef write_setting
|
||||
}
|
||||
virtual ~settings()
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace libopenmpt
|
||||
|
||||
|
||||
#endif // LIBOPENMPT_PLUGIN_SETTINGS_HPP
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* libopenmpt_stream_callbacks_buffer.h
|
||||
* ------------------------------------
|
||||
* Purpose: libopenmpt public c interface
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H
|
||||
|
||||
#include "libopenmpt.h"
|
||||
|
||||
/* The use of this header requires:
|
||||
|
||||
#include <libopenmpt/libopenmpt.h>
|
||||
#if defined( LIBOPENMPT_STREAM_CALLBACKS_BUFFER )
|
||||
#include <libopenmpt/libopenmpt_stream_callbacks_buffer.h>
|
||||
#else
|
||||
#error "libopenmpt too old."
|
||||
#endif
|
||||
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*! \addtogroup libopenmpt_c
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct openmpt_stream_buffer {
|
||||
const void * file_data; /* or prefix data IFF prefix_size < file_size */
|
||||
int64_t file_size;
|
||||
int64_t file_pos;
|
||||
int64_t prefix_size;
|
||||
int overflow;
|
||||
} openmpt_stream_buffer;
|
||||
|
||||
static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
|
||||
openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
|
||||
int64_t offset = 0;
|
||||
int64_t begpos = 0;
|
||||
int64_t endpos = 0;
|
||||
size_t valid_bytes = 0;
|
||||
if ( !s ) {
|
||||
return 0;
|
||||
}
|
||||
offset = bytes;
|
||||
begpos = s->file_pos;
|
||||
endpos = s->file_pos;
|
||||
valid_bytes = 0;
|
||||
endpos = (uint64_t)endpos + (uint64_t)offset;
|
||||
if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) {
|
||||
/* integer wrapped */
|
||||
return 0;
|
||||
}
|
||||
if ( bytes == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( begpos >= s->file_size ) {
|
||||
return 0;
|
||||
}
|
||||
if ( endpos > s->file_size ) {
|
||||
/* clip to eof */
|
||||
bytes = bytes - (size_t)( endpos - s->file_size );
|
||||
endpos = endpos - ( endpos - s->file_size );
|
||||
}
|
||||
memset( dst, 0, bytes );
|
||||
if ( begpos >= s->prefix_size ) {
|
||||
s->overflow = 1;
|
||||
valid_bytes = 0;
|
||||
} else if ( endpos > s->prefix_size ) {
|
||||
s->overflow = 1;
|
||||
valid_bytes = bytes - (size_t)( endpos - s->prefix_size );
|
||||
} else {
|
||||
valid_bytes = bytes;
|
||||
}
|
||||
memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes );
|
||||
s->file_pos = s->file_pos + bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) {
|
||||
openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
|
||||
int result = -1;
|
||||
if ( !s ) {
|
||||
return -1;
|
||||
}
|
||||
switch ( whence ) {
|
||||
case OPENMPT_STREAM_SEEK_SET:
|
||||
if ( offset < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
if ( offset > s->file_size ) {
|
||||
return -1;
|
||||
}
|
||||
s->file_pos = offset;
|
||||
result = 0;
|
||||
break;
|
||||
case OPENMPT_STREAM_SEEK_CUR:
|
||||
do {
|
||||
int64_t oldpos = s->file_pos;
|
||||
int64_t pos = s->file_pos;
|
||||
pos = (uint64_t)pos + (uint64_t)offset;
|
||||
if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) {
|
||||
/* integer wrapped */
|
||||
return -1;
|
||||
}
|
||||
if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
|
||||
/* integer wrapped */
|
||||
return -1;
|
||||
}
|
||||
s->file_pos = pos;
|
||||
} while(0);
|
||||
result = 0;
|
||||
break;
|
||||
case OPENMPT_STREAM_SEEK_END:
|
||||
if ( offset > 0 ) {
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
int64_t oldpos = s->file_pos;
|
||||
int64_t pos = s->file_pos;
|
||||
pos = s->file_size;
|
||||
pos = (uint64_t)pos + (uint64_t)offset;
|
||||
if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
|
||||
/* integer wrapped */
|
||||
return -1;
|
||||
}
|
||||
s->file_pos = pos;
|
||||
} while(0);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int64_t openmpt_stream_buffer_tell_func( void * stream ) {
|
||||
openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
|
||||
if ( !s ) {
|
||||
return -1;
|
||||
}
|
||||
return s->file_pos;
|
||||
}
|
||||
|
||||
static void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) {
|
||||
memset( buffer, 0, sizeof( openmpt_stream_buffer ) );
|
||||
buffer->file_data = file_data;
|
||||
buffer->file_size = file_size;
|
||||
buffer->file_pos = 0;
|
||||
buffer->prefix_size = file_size;
|
||||
buffer->overflow = 0;
|
||||
}
|
||||
|
||||
#define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \
|
||||
openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \
|
||||
(buffer_)->prefix_size = (prefix_size_); \
|
||||
} while(0)
|
||||
|
||||
#define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow )
|
||||
|
||||
/*! \brief Provide openmpt_stream_callbacks for in-memoy buffers
|
||||
*
|
||||
* Fills openmpt_stream_callbacks suitable for passing an in-memory buffer as a stream parameter to functions doing file input/output.
|
||||
*
|
||||
* \remarks The stream argument must be passed as `(void*)(openmpt_stream_buffer*)stream_buffer`.
|
||||
* \sa \ref libopenmpt_c_fileio
|
||||
* \sa openmpt_stream_callbacks
|
||||
* \sa openmpt_could_open_probability2
|
||||
* \sa openmpt_probe_file_header_from_stream
|
||||
* \sa openmpt_module_create2
|
||||
*/
|
||||
static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void) {
|
||||
openmpt_stream_callbacks retval;
|
||||
memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
|
||||
retval.read = openmpt_stream_buffer_read_func;
|
||||
retval.seek = openmpt_stream_buffer_seek_func;
|
||||
retval.tell = openmpt_stream_buffer_tell_func;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* libopenmpt_stream_callbacks_fd.h
|
||||
* --------------------------------
|
||||
* Purpose: libopenmpt public c interface
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_STREAM_CALLBACKS_FD_H
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_FD_H
|
||||
|
||||
#include "libopenmpt.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*! \addtogroup libopenmpt_c
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for fd crossing CRT boundaries. */
|
||||
|
||||
static size_t openmpt_stream_fd_read_func( void * stream, void * dst, size_t bytes ) {
|
||||
int fd = 0;
|
||||
#if defined(_MSC_VER)
|
||||
size_t retval = 0;
|
||||
int to_read = 0;
|
||||
int ret_read = 0;
|
||||
#else
|
||||
ssize_t retval = 0;
|
||||
#endif
|
||||
fd = (int)(uintptr_t)stream;
|
||||
if ( fd < 0 ) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
retval = 0;
|
||||
while ( bytes > 0 ) {
|
||||
to_read = 0;
|
||||
if ( bytes < (size_t)INT_MAX ) {
|
||||
to_read = (int)bytes;
|
||||
} else {
|
||||
to_read = INT_MAX;
|
||||
}
|
||||
ret_read = _read( fd, dst, to_read );
|
||||
if ( ret_read <= 0 ) {
|
||||
return retval;
|
||||
}
|
||||
bytes -= ret_read;
|
||||
retval += ret_read;
|
||||
}
|
||||
#else
|
||||
retval = read( fd, dst, bytes );
|
||||
#endif
|
||||
if ( retval <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! \brief Provide openmpt_stream_callbacks for standard POSIX file descriptors
|
||||
*
|
||||
* Fills openmpt_stream_callbacks suitable for passing a POSIX filer descriptor as a stream parameter to functions doing file input/output.
|
||||
*
|
||||
* \remarks The stream argument must be passed as `(void*)(uintptr_t)(int)fd`.
|
||||
* \sa \ref libopenmpt_c_fileio
|
||||
* \sa openmpt_stream_callbacks
|
||||
* \sa openmpt_could_open_probability2
|
||||
* \sa openmpt_probe_file_header_from_stream
|
||||
* \sa openmpt_module_create2
|
||||
*/
|
||||
static openmpt_stream_callbacks openmpt_stream_get_fd_callbacks(void) {
|
||||
openmpt_stream_callbacks retval;
|
||||
memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
|
||||
retval.read = openmpt_stream_fd_read_func;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* LIBOPENMPT_STREAM_CALLBACKS_FD_H */
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* libopenmpt_stream_callbacks_file.h
|
||||
* ----------------------------------
|
||||
* Purpose: libopenmpt public c interface
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_STREAM_CALLBACKS_FILE_H
|
||||
#define LIBOPENMPT_STREAM_CALLBACKS_FILE_H
|
||||
|
||||
#include "libopenmpt.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <wchar.h> /* off_t */
|
||||
#endif
|
||||
|
||||
/*! \addtogroup libopenmpt_c
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This stuff has to be in a header file because of possibly different MSVC CRTs which cause problems for FILE * crossing CRT boundaries. */
|
||||
|
||||
static size_t openmpt_stream_file_read_func( void * stream, void * dst, size_t bytes ) {
|
||||
FILE * f = 0;
|
||||
size_t retval = 0;
|
||||
f = (FILE*)stream;
|
||||
if ( !f ) {
|
||||
return 0;
|
||||
}
|
||||
retval = fread( dst, 1, bytes, f );
|
||||
if ( retval <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int openmpt_stream_file_seek_func( void * stream, int64_t offset, int whence ) {
|
||||
FILE * f = 0;
|
||||
int fwhence = 0;
|
||||
f = (FILE*)stream;
|
||||
if ( !f ) {
|
||||
return -1;
|
||||
}
|
||||
switch ( whence ) {
|
||||
#if defined(SEEK_SET)
|
||||
case OPENMPT_STREAM_SEEK_SET:
|
||||
fwhence = SEEK_SET;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SEEK_CUR)
|
||||
case OPENMPT_STREAM_SEEK_CUR:
|
||||
fwhence = SEEK_CUR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SEEK_END)
|
||||
case OPENMPT_STREAM_SEEK_END:
|
||||
fwhence = SEEK_END;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
return _fseeki64( f, offset, fwhence ) ? -1 : 0;
|
||||
#elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1)
|
||||
return fseeko( f, offset, fwhence ) ? -1 : 0;
|
||||
#else
|
||||
return fseek( f, offset, fwhence ) ? -1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int64_t openmpt_stream_file_tell_func( void * stream ) {
|
||||
FILE * f = 0;
|
||||
int64_t retval = 0;
|
||||
f = (FILE*)stream;
|
||||
if ( !f ) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
retval = _ftelli64( f );
|
||||
#elif defined(_POSIX_SOURCE) && (_POSIX_SOURCE == 1)
|
||||
retval = ftello( f );
|
||||
#else
|
||||
retval = ftell( f );
|
||||
#endif
|
||||
if ( retval < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! \brief Provide openmpt_stream_callbacks for standard C FILE objects
|
||||
*
|
||||
* Fills openmpt_stream_callbacks suitable for passing a standard C FILE object as a stream parameter to functions doing file input/output.
|
||||
*
|
||||
* \remarks The stream argument must be passed as `(void*)(FILE*)file`.
|
||||
* \sa \ref libopenmpt_c_fileio
|
||||
* \sa openmpt_stream_callbacks
|
||||
* \sa openmpt_could_open_probability2
|
||||
* \sa openmpt_probe_file_header_from_stream
|
||||
* \sa openmpt_module_create2
|
||||
*/
|
||||
static openmpt_stream_callbacks openmpt_stream_get_file_callbacks(void) {
|
||||
openmpt_stream_callbacks retval;
|
||||
memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
|
||||
retval.read = openmpt_stream_file_read_func;
|
||||
retval.seek = openmpt_stream_file_seek_func;
|
||||
retval.tell = openmpt_stream_file_tell_func;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* LIBOPENMPT_STREAM_CALLBACKS_FILE_H */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* libopenmpt_test.cpp
|
||||
* -------------------
|
||||
* Purpose: libopenmpt test suite driver
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
#include "libopenmpt_internal.h"
|
||||
|
||||
#include "test/test.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
|
||||
#include <clocale>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace OpenMPT;
|
||||
|
||||
#if defined( LIBOPENMPT_BUILD_TEST )
|
||||
|
||||
#if (defined(_WIN32) || defined(WIN32)) && (defined(_UNICODE) || defined(UNICODE))
|
||||
#if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER))
|
||||
// mingw-w64 g++ does only default to special C linkage for "main", but not for "wmain" (see <https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/>).
|
||||
extern "C" int wmain( int /*argc*/ , wchar_t * /*argv*/ [] );
|
||||
extern "C"
|
||||
#endif
|
||||
int wmain( int /*argc*/ , wchar_t * /*argv*/ [] ) {
|
||||
#else
|
||||
int main( int /*argc*/ , char * /*argv*/ [] ) {
|
||||
#endif
|
||||
try {
|
||||
|
||||
// run test with "C" / classic() locale
|
||||
Test::DoTests();
|
||||
|
||||
// try setting the C locale to the user locale
|
||||
setlocale( LC_ALL, "" );
|
||||
|
||||
// run all tests again with a set C locale
|
||||
Test::DoTests();
|
||||
|
||||
// try to set the C and C++ locales to the user locale
|
||||
try {
|
||||
std::locale old = std::locale::global( std::locale( "" ) );
|
||||
(void)old;
|
||||
} catch ( ... ) {
|
||||
// Setting c++ global locale does not work.
|
||||
// This is no problem for libopenmpt, just continue.
|
||||
}
|
||||
|
||||
// and now, run all tests once again
|
||||
Test::DoTests();
|
||||
|
||||
} catch ( const std::exception & e ) {
|
||||
std::cerr << "TEST ERROR: exception: " << ( e.what() ? e.what() : "" ) << std::endl;
|
||||
return -1;
|
||||
} catch ( ... ) {
|
||||
std::cerr << "TEST ERROR: unknown exception" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // LIBOPENMPT_BUILD_TEST
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* libopenmpt_version.h
|
||||
* --------------------
|
||||
* Purpose: libopenmpt public interface version
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENMPT_VERSION_H
|
||||
#define LIBOPENMPT_VERSION_H
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
/*! \addtogroup libopenmpt
|
||||
@{
|
||||
*/
|
||||
|
||||
/*! \brief libopenmpt major version number */
|
||||
#define OPENMPT_API_VERSION_MAJOR 0
|
||||
/*! \brief libopenmpt minor version number */
|
||||
#define OPENMPT_API_VERSION_MINOR 6
|
||||
/*! \brief libopenmpt patch version number */
|
||||
#define OPENMPT_API_VERSION_PATCH 6
|
||||
/*! \brief libopenmpt pre-release tag */
|
||||
#define OPENMPT_API_VERSION_PREREL ""
|
||||
/*! \brief libopenmpt pre-release flag */
|
||||
#define OPENMPT_API_VERSION_IS_PREREL 0
|
||||
|
||||
/*! \brief libopenmpt version number as a single integer value
|
||||
* \since 0.3
|
||||
* \remarks Use the following shim if you need to support earlier libopenmpt versions:
|
||||
* \code
|
||||
* #include <libopenmpt/libopenmpt_version.h>
|
||||
* #if !defined(OPENMPT_API_VERSION_MAKE)
|
||||
* #define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0))
|
||||
* #endif
|
||||
* \endcode
|
||||
*/
|
||||
#define OPENMPT_API_VERSION_MAKE(major, minor, patch) (((major)<<24)|((minor)<<16)|((patch)<<0))
|
||||
|
||||
/*! \brief libopenmpt API version number */
|
||||
#define OPENMPT_API_VERSION OPENMPT_API_VERSION_MAKE(OPENMPT_API_VERSION_MAJOR, OPENMPT_API_VERSION_MINOR, OPENMPT_API_VERSION_PATCH)
|
||||
|
||||
/*! \brief Check whether the libopenmpt API is at least the provided version
|
||||
* \since 0.3
|
||||
* \remarks Use the following shim if you need to support earlier libopenmpt versions:
|
||||
* \code
|
||||
* #include <libopenmpt/libopenmpt_version.h>
|
||||
* #if !defined(OPENMPT_API_VERSION_AT_LEAST)
|
||||
* #define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch)))
|
||||
* #endif
|
||||
* \endcode
|
||||
*/
|
||||
#define OPENMPT_API_VERSION_AT_LEAST(major, minor, patch) (OPENMPT_API_VERSION >= OPENMPT_API_VERSION_MAKE((major), (minor), (patch)))
|
||||
|
||||
/*! \brief Check whether the libopenmpt API is before the provided version
|
||||
* \since 0.3
|
||||
* \remarks Use the following shim if you need to support earlier libopenmpt versions:
|
||||
* \code
|
||||
* #include <libopenmpt/libopenmpt_version.h>
|
||||
* #if !defined(OPENMPT_API_VERSION_BEFORE)
|
||||
* #define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch)))
|
||||
* #endif
|
||||
* \endcode
|
||||
*/
|
||||
#define OPENMPT_API_VERSION_BEFORE(major, minor, patch) (OPENMPT_API_VERSION < OPENMPT_API_VERSION_MAKE((major), (minor), (patch)))
|
||||
|
||||
#define OPENMPT_API_VERSION_HELPER_STRINGIZE(x) #x
|
||||
#define OPENMPT_API_VERSION_STRINGIZE(x) OPENMPT_API_VERSION_HELPER_STRINGIZE(x)
|
||||
#define OPENMPT_API_VERSION_STRING OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MAJOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_MINOR) "." OPENMPT_API_VERSION_STRINGIZE(OPENMPT_API_VERSION_PATCH) OPENMPT_API_VERSION_PREREL
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* LIBOPENMPT_VERSION_H */
|
|
@ -0,0 +1,8 @@
|
|||
LIBOPENMPT_VERSION_MAJOR=0
|
||||
LIBOPENMPT_VERSION_MINOR=6
|
||||
LIBOPENMPT_VERSION_PATCH=6
|
||||
LIBOPENMPT_VERSION_PREREL=
|
||||
|
||||
LIBOPENMPT_LTVER_CURRENT=3
|
||||
LIBOPENMPT_LTVER_REVISION=6
|
||||
LIBOPENMPT_LTVER_AGE=3
|
|
@ -0,0 +1,216 @@
|
|||
|
||||
#include "svn_version.h"
|
||||
#include "libopenmpt_version.h"
|
||||
#include <winver.h>
|
||||
|
||||
#if 0
|
||||
// defined externally by build system
|
||||
#define MPT_BUILD_VER_FILENAME "libopenmpt.dll"
|
||||
#define MPT_BUILD_VER_FILEDESC "libopenmpt"
|
||||
#undef MPT_BUILD_VER_EXE
|
||||
#define MPT_BUILD_VER_DLL 1
|
||||
#define MPT_BUILD_VER_SPECIAL_PREFIX ""
|
||||
#define MPT_BUILD_VER_SPECIAL_SUFFIX ""
|
||||
#endif
|
||||
|
||||
#if defined(MPT_BUILD_VER_FILENAME) && (defined(MPT_BUILD_VER_EXE) || defined(MPT_BUILD_VER_DLL))
|
||||
//#if defined(OPENMPT_VERSION_REVISION) && defined(OPENMPT_VERSION_DIRTY) && defined(OPENMPT_VERSION_MIXEDREVISIONS) && defined(OPENMPT_VERSION_IS_PACKAGE)
|
||||
//#if (OPENMPT_VERSION_REVISION > 0)
|
||||
|
||||
#if defined(OPENMPT_VERSION_REVISION)
|
||||
#if (OPENMPT_VERSION_REVISION > 0)
|
||||
#define OPENMPT_VERSION_HAVE_REVISION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VER_STRINGIZE_HELPER(x) #x
|
||||
#define VER_STRINGIZE(x) VER_STRINGIZE_HELPER(x)
|
||||
|
||||
#if defined(OPENMPT_VERSION_DIRTY) && defined(OPENMPT_VERSION_MIXEDREVISIONS) && defined(OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if (OPENMPT_VERSION_DIRTY)
|
||||
#define VER_FILEVERSION_SRC 2
|
||||
#elif (OPENMPT_VERSION_MIXEDREVISIONS)
|
||||
#define VER_FILEVERSION_SRC 1
|
||||
#elif (OPENMPT_VERSION_IS_PACKAGE)
|
||||
#define VER_FILEVERSION_SRC 0
|
||||
#else
|
||||
#define VER_FILEVERSION_SRC 0
|
||||
#endif
|
||||
#else
|
||||
#define VER_FILEVERSION_SRC 0
|
||||
#endif
|
||||
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION OPENMPT_API_VERSION_MAJOR,OPENMPT_API_VERSION_MINOR,OPENMPT_API_VERSION_PATCH,OPENMPT_VERSION_REVISION
|
||||
#define VER_FILEVERSION1_STR OPENMPT_API_VERSION_STRING
|
||||
#else
|
||||
#define VER_FILEVERSION OPENMPT_API_VERSION_MAJOR,OPENMPT_API_VERSION_MINOR,OPENMPT_API_VERSION_PATCH,0
|
||||
#define VER_FILEVERSION1_STR OPENMPT_API_VERSION_STRING
|
||||
#endif
|
||||
|
||||
#if defined(OPENMPT_VERSION_DIRTY) && defined(OPENMPT_VERSION_MIXEDREVISIONS) && defined(OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if (OPENMPT_VERSION_DIRTY)
|
||||
#if (OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION) "modified.pkg"
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR "+modified.pkg"
|
||||
#endif
|
||||
#else
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION) ".modified"
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR "+modified"
|
||||
#endif
|
||||
#endif
|
||||
#elif (OPENMPT_VERSION_MIXEDREVISIONS)
|
||||
#if (OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION) ".modified.pkg"
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR "+modified.pkg"
|
||||
#endif
|
||||
#else
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION) ".modified"
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR "+modified"
|
||||
#endif
|
||||
#endif
|
||||
#elif (OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION) "pkg"
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR "+pkg"
|
||||
#endif
|
||||
#else
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION)
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR ""
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if defined(OPENMPT_VERSION_HAVE_REVISION)
|
||||
#define VER_FILEVERSION2_STR "+r" VER_STRINGIZE(OPENMPT_VERSION_REVISION)
|
||||
#else
|
||||
#define VER_FILEVERSION2_STR ""
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VER_FILEVERSION_STR VER_FILEVERSION1_STR VER_FILEVERSION2_STR
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define VER_DEBUG VS_FF_DEBUG
|
||||
#else
|
||||
#define VER_DEBUG 0
|
||||
#endif
|
||||
|
||||
#if defined(OPENMPT_VERSION_DIRTY) && defined(OPENMPT_VERSION_MIXEDREVISIONS)
|
||||
#if ((OPENMPT_VERSION_DIRTY) || (OPENMPT_VERSION_MIXEDREVISIONS))
|
||||
#define VER_PATCHED VS_FF_PATCHED
|
||||
#else
|
||||
#define VER_PATCHED 0
|
||||
#endif
|
||||
#else
|
||||
#define VER_PATCHED 0
|
||||
#endif
|
||||
|
||||
#if (OPENMPT_API_VERSION_IS_PREREL)
|
||||
#define VER_PRERELEASE VS_FF_PRERELEASE
|
||||
#else
|
||||
#define VER_PRERELEASE 0
|
||||
#endif
|
||||
|
||||
#if defined(OPENMPT_VERSION_REVISION) && defined(OPENMPT_VERSION_DIRTY) && defined(OPENMPT_VERSION_MIXEDREVISIONS) && defined(OPENMPT_VERSION_IS_PACKAGE)
|
||||
#if (OPENMPT_VERSION_REVISION > 0)
|
||||
#define VER_PRIVATEBUILD 0
|
||||
#define VER_PRIVATEBUILD_STR ""
|
||||
#else
|
||||
#define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD
|
||||
#define VER_PRIVATEBUILD_STR "unknwon"
|
||||
#endif
|
||||
#else
|
||||
#define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD
|
||||
#define VER_PRIVATEBUILD_STR "unknwon"
|
||||
#endif
|
||||
|
||||
#if defined(MPT_BUILD_RETRO) || defined(MPT_BUILD_VER_SPECIAL_PREFIX) || defined(MPT_BUILD_VER_SPECIAL_SUFFIX)
|
||||
#ifndef MPT_BUILD_VER_SPECIAL_PREFIX
|
||||
#define MPT_BUILD_VER_SPECIAL_PREFIX ""
|
||||
#endif
|
||||
#ifndef MPT_BUILD_VER_SPECIAL_SUFFIX
|
||||
#define MPT_BUILD_VER_SPECIAL_SUFFIX ""
|
||||
#endif
|
||||
#define VER_SPECIALBUILD VS_FF_SPECIALBUILD
|
||||
#if defined(MPT_BUILD_RETRO)
|
||||
#define VER_SPECIALBUILD_STR MPT_BUILD_VER_SPECIAL_PREFIX "+retro" MPT_BUILD_VER_SPECIAL_SUFFIX
|
||||
#else
|
||||
#define VER_SPECIALBUILD_STR MPT_BUILD_VER_SPECIAL_PREFIX MPT_BUILD_VER_SPECIAL_SUFFIX
|
||||
#endif
|
||||
#elif defined(MPT_BUILD_VER_SPECIAL_PREFIX) || defined(MPT_BUILD_VER_SPECIAL_SUFFIX)
|
||||
#define VER_SPECIALBUILD 1
|
||||
#define VER_SPECIALBUILD_STR MPT_BUILD_VER_SPECIAL_PREFIX MPT_BUILD_VER_SPECIAL_SUFFIX
|
||||
#else
|
||||
#define VER_SPECIALBUILD 0
|
||||
#define VER_SPECIALBUILD_STR ""
|
||||
#endif
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#define VER_FILEFLAGS (VER_DEBUG|VER_PATCHED|VER_PRERELEASE|VER_PRIVATEBUILD|VER_SPECIALBUILD)
|
||||
|
||||
#if defined(MPT_BUILD_VER_EXE)
|
||||
#define VER_FILETYPE VFT_APP
|
||||
#elif defined(MPT_BUILD_VER_DLL)
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#else
|
||||
#define VER_FILETYPE VFT_UNKNOWN
|
||||
#endif
|
||||
|
||||
#define VER_FILENAME_STR MPT_BUILD_VER_FILENAME
|
||||
|
||||
#if defined(MPT_BUILD_VER_FILEDESC)
|
||||
#define VER_FILEDESC_STR MPT_BUILD_VER_FILEDESC
|
||||
#else
|
||||
#define VER_FILEDESC_STR MPT_BUILD_VER_FILENAME
|
||||
#endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_FILEVERSION
|
||||
FILEFLAGSMASK VER_FILEFLAGSMASK
|
||||
FILEFLAGS VER_FILEFLAGS
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VER_FILETYPE
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "OpenMPT (https://openmpt.org)"
|
||||
VALUE "FileDescription", VER_FILEDESC_STR
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", VER_FILENAME_STR
|
||||
VALUE "LegalCopyright", "Copyright © 2004-2022 OpenMPT Project Developers and Contributors, Copyright © 1997-2003 Olivier Lapicque"
|
||||
VALUE "OriginalFilename", VER_FILENAME_STR
|
||||
VALUE "ProductName", "libopenmpt"
|
||||
VALUE "ProductVersion", VER_FILEVERSION_STR
|
||||
#if VER_PRIVATEBUILD
|
||||
VALUE "PrivateBuild", VER_PRIVATEBUILD_STR
|
||||
#endif
|
||||
#if VER_SPECIALBUILD
|
||||
VALUE "SpecialBuild", VER_SPECIALBUILD_STR
|
||||
#endif
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
//#endif
|
||||
//#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by libopenmpt_plugin_gui.rc
|
||||
//
|
||||
#define IDD_SETTINGS 101
|
||||
#define IDD_FILEINFO 102
|
||||
#define IDC_COMBO_SAMPLERATE 1001
|
||||
#define IDC_COMBO_CHANNELS 1002
|
||||
#define IDC_SLIDER_GAIN 1003
|
||||
#define IDC_COMBO_INTERPOLATION 1004
|
||||
#define IDC_COMBO_REPEAT 1005
|
||||
#define IDC_SLIDER_STEREOSEPARATION 1006
|
||||
#define IDC_COMBO_RAMPING 1007
|
||||
#define IDC_FILEINFO 1008
|
||||
#define IDC_COMBO_AMIGA_FILTER 1008
|
||||
#define IDC_CHECK_AMIGA_RESAMPLER 1009
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1010
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
1893
Src/external_dependencies/openmpt-trunk/libopenmpt/xmp-openmpt.cpp
Normal file
1893
Src/external_dependencies/openmpt-trunk/libopenmpt/xmp-openmpt.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue