Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View 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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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.

View file

@ -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.

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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`.

View file

@ -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
*
*/

View file

@ -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).

View file

@ -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.

View file

@ -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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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}

File diff suppressed because it is too large Load diff

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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, &regkey ) == 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, &regkey, 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

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff