@DATABASE "xmodule" @MASTER "Work:SC/XM/Autodocs/xmodule.doc" @REMARK This file was created by ADtoHT 2.1 on 08-Apr-97 12:17:15 @REMARK Do not edit @REMARK ADtoHT is © 1993-1995 Christian Stieber @NODE MAIN "xmodule.doc" @{b}xmodule@{ub} @{"background" LINK "background"} @{"xmActivateSong()" LINK "xmActivateSong"} @{"xmAddHook()" LINK "xmAddHook"} @{"xmAddHookA()" LINK "xmAddHook"} @{"xmAddInstrument()" LINK "xmAddInstrumentA"} @{"xmAddInstrumentA()" LINK "xmAddInstrumentA"} @{"xmAddPattern()" LINK "xmAddPatternA"} @{"xmAddPatternA()" LINK "xmAddPatternA"} @{"xmAddSong()" LINK "xmAddSongA"} @{"xmAddSongA()" LINK "xmAddSongA"} @{"xmCreateSong()" LINK "xmCreateSong"} @{"xmCreateSongA()" LINK "xmCreateSong"} @{"xmDeleteSong()" LINK "xmDeleteSong"} @{"xmDisplayMessage()" LINK "xmDisplayMessage"} @{"xmDisplayMessageA()" LINK "xmDisplayMessage"} @{"xmDisplayProgress()" LINK "xmDisplayProgress"} @{"xmIdentifyModule()" LINK "xmIdentifyModule"} @{"xmLoadModule()" LINK "xmLoadModuleA"} @{"xmLoadModuleA()" LINK "xmLoadModuleA"} @{"xmLockActiveSong()" LINK "xmLockActiveSong"} @{"xmProcessSong()" LINK "xmProcessSongA"} @{"xmProcessSongA()" LINK "xmProcessSongA"} @{"xmRemHook()" LINK "xmRemHook"} @{"xmRemHookA()" LINK "xmRemHook"} @{"xmRemInstrument()" LINK "xmRemInstrument"} @{"xmRemPattern()" LINK "xmRemPattern"} @{"xmRemSong()" LINK "xmRemSong"} @{"xmSaveModule()" LINK "xmSaveModuleA"} @{"xmSaveModuleA()" LINK "xmSaveModuleA"} @{"xmSetInstrument()" LINK "xmSetInstrumentA"} @{"xmSetInstrumentA()" LINK "xmSetInstrumentA"} @{"xmSetPattern()" LINK "xmSetPatternA"} @{"xmSetPatternA()" LINK "xmSetPatternA"} @{"xmSetSongLen()" LINK "xmSetSongLen"} @ENDNODE @NODE "background" "xmodule/background (information)" INTRODUCTION The xmodule.library is an API that provides access to the XModule song management engine, as well as other general pourpose services. Hooks and external applications can use this library to create, load, save and modify songs. The xmodule.library does not exist as a stand alone shared libray. Instead, it's code is contained inside the main XModule executable (altrough it's logically independant from the rest of the XModule code). XModule adds the xmodule.library to the exec libray list at startup time, unless it finds one already in the list (this might happen when multiple copies of XModule are running at the same time). PUBLIC SONGS The xmodule.library maintains a list of public songs which can be used by all applications which opened the library. Each song in the list is protected from multiple task access by a SignalSemaphore, and whole list is also protected by another semaphore. The locking mechanism is very simple: before you can access a song you must obtain its semaphore, and you must release it as soon as you are done with it. If you are locking a song to just to read some information (i.e.: you don't want to modify anything), you should obtain a shared lock instead of an exclusive one. The list must be locked whenever you want to add or remove a song, or when you scan it in any way. Since public songs could be modified or even deleted by other tasks, do not make your songs public unless your code is smart enough to handle all possible situations. HOOKS Actually, most modular programs call them `modules', but it would have created a lot of confusion with a program like XModule :-). Hooks are programs that add some kind of functionality to XModule. External hook files are standard shared libraries which will open the xmodule.library when they are loaded and call @{"xmAddHookA()" LINK "xmodule/xmAddHook"} to add themselves to a list of hooks maintained by the library. Currently, XModule supports two kinds of hooks: loaders and savers. Loader hooks can also provide a function which identifies a particular module format. An external hook libray may also contain several hooks. Putting a loader and a saver for one particolar format together in one libray is generally a good idea, while making a hook with hundereds of loaders and savers isn't a good move because it makes the whole concept of external hooks quite useless. Grouping different versions or variants of one format together in one external hook is acceptable. SEE ALSO songclass/--background--, exec/ObtainSemaphore() @ENDNODE @NODE "xmActivateSong" "xmodule/xmActivateSong()" @{b} NAME@{ub} xmActivateSong -- Makes a song the active one@{b} SYNOPSIS@{ub} success = xmActivateSong(songInfo); D0 A0 ULONG xmActivateSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b} FUNCTION@{ub} Makes the passed song the currently active one. It's pointer will be stored in the public song list and most actions will happen on this song by default.@{b} INPUTS@{ub} songInfo - song to be activated. If NULL, this function will take no action.@{b} RESULT@{ub} success - Will be 0 for failure, in which case the song will not be removed from the song list. Currently, xmActivateSong() will never fail.@{b} NOTE@{ub} In order to activate a song, you must own a shared lock on it. Please do not hog this lock for a long time when xmActivateSong() returns, because most internal routines try to lock the current song before taking any action.@{b} SEE ALSO@{ub} @ENDNODE @NODE "xmAddHook" "xmodule/xmAddHook()" @{b} NAME@{ub} xmAddHookA -- Creates a new XModule Hook xmAddHook -- Varargs stub for xmAddHookA@{b} SYNOPSIS@{ub} hook = xmAddHookA(tagList) D0 A0 @{"struct XMHook" LINK "xmodule.h/File" 92} *xmAddHookA(struct TagItem *); hook = xmAddHook(Tag1,...) @{"struct XMHook" LINK "xmodule.h/File" 92} *xmAddHook(ULONG,...);@{b} FUNCTION@{ub} Creates a new XMHook structure and fills it in with data supplied with the TagList. Adds the newly created Hook to the appropriate list.@{b} INPUTS@{ub} tagList - pointer to a tag list specifying how to initialize the XMHook structure.@{b} TAGS@{ub} @{"XMHOOK_Type" LINK "xmodule.h/File" 235} - (ULONG) Defines the pourpose of this hook. Possible values are currently @{"NT_XMLOADER" LINK "xmodule.h/File" 138} and @{"NT_XMSAVER" LINK "xmodule.h/File" 139}. (This tag is REQUIRED). @{"XMHOOK_Name" LINK "xmodule.h/File" 236} - (STRPTR) ti_Data contains a short name for the hook (e.g: "SoundTracker"). This name will appear in the Savers list if this hook is a saver and will be passed as an argument for some ARexx commands, so please use a single word name. (This tag is REQUIRED). @{"XMHOOK_Priority" LINK "xmodule.h/File" 237} - (BYTE) Priority to give to this hook. Hooks with higher priorities will be used before lower priority ones and will come first in lists shown to the user. Valid range is -128..+127, but please restrict to a -20..+20 interval for normal cases. (Defaults to 0). @{"XMHOOK_Descr" LINK "xmodule.h/File" 238} - (STRPTR) Verbose description of the hook (without newlines). (Defaults to NULL). @{"XMHOOK_Author" LINK "xmodule.h/File" 239} - (STRPTR) Author's name. Please, just put your full name here; no greetings, copyright notices, etc. (Defaults to NULL). @{"XMHOOK_ID" LINK "xmodule.h/File" 240} - (ULONG) This is a unique, IFF-style identifier for the format. If the format is an IFF format, it must be the same of the FORM ID. (Defaults to 0, this tag is required for IFF loaders and savers). @{"XMHOOK_Flags" LINK "xmodule.h/File" 241} - (ULONG) Sets miscellaneous flags for this hook. See xmodule.h for possible flags. @{"XMHOOK_LibraryBase" LINK "xmodule.h/File" 243} - (struct Library *) Pointer to the library base for external hooks. This pointer will be used to open the library when the hook is created and to close it when the hook is deleted. If you do not pass this tag, you must find some other way to keep your code in memory until one or more of your hooks are active. XModule will close your library just after calling the SetupXMHook() function. (Defaults to NULL). @{"XMHOOK_UserData" LINK "xmodule.h/File" 242} - (APTR) ti_Data will be stored in the xmh_UserData field of the XMHook structure. This field can come andy to store private data. (Defaults to NULL). XMHOOK_RemoveHookFunc - (APTR) Pointer to a function which will be called upon removing the hook. This function can be used to free any private resources allocated by the hook when it was created. The template for the function is: void RemoveHookFunc (@{"struct XMHook" LINK "xmodule.h/File" 92} *hook); A0 @{"XMHOOK_LoadModFunc" LINK "xmodule.h/File" 245} - (APTR) Pointer to the hook function which loads a module. The template for the function is: LONG LoadModFunc (BPTR fileHandle, @{"struct SongInfo" LINK "songclass.h/File" 284} *song, D0 A0 @{"struct XMHook" LINK "xmodule.h/File" 92} *loader); A1 `fileHandle' is an open file to load the module from. The caller will take care to close it for you. The loader should return RETURN_OK for success, or any other AmigaDOS error code to mean failure. In particular, RETURN_WARN indicates that something went wrong, but the song is ok. The special error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} can be used when some dos.library call (e.g.: Read()) failed. In the latter case, the AmigaDOS IoErr value should be set to explain the specific cause of the problem. (This tag is required by all @{"NT_XMLOADER" LINK "xmodule.h/File" 138} type hooks). @{"XMHOOK_SaveModFunc" LINK "xmodule.h/File" 246} - (APTR) Pointer to the hook function which saves a module. The template for the function is: LONG SaveModFunc (BPTR fileHandle, @{"struct SongInfo" LINK "songclass.h/File" 284} *song, D0 A0 @{"struct XMHook" LINK "xmodule.h/File" 92} *saver); A1 fileHandle is an open file to save the module to. The caller will take care to close it for you. The saver should return RETURN_OK for success, or any other AmigaDOS error code to mean failure. In particular, RETURN_WARN indicates that something went wrong, but the song is ok. The special error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} can be used when some dos.library call (e.g.: Read()) failed. In the latter case, the AmigaDOS IoErr value should be set to explain the specific cause of the problem. (This tag is required by all @{"NT_XMSAVER" LINK "xmodule.h/File" 139} type hooks). @{"XMHOOK_IdentifyModFunc" LINK "xmodule.h/File" 247} - (APTR) Pointer to the hook function which identifies a module format. The template for the function is: @{"struct XMHook" LINK "xmodule.h/File" 92} *IdentifyModFunc (BPTR fileHandle, D0 @{"struct XMHook" LINK "xmodule.h/File" 92} *hook,struct TagItem *tagList); A0 A1 fileHandle is an open file to try the identification on. The caller will take care to close it. NOTE: Do not make assumptions on the initial file position (e.g: seek yourself to position 0 if you need to). This funtion should return a pointer to a valid loader (usually the one passed in) if the format is recognized, NULL otherwhise. (This tag is required by all @{"NT_XMLOADER" LINK "xmodule.h/File" 138} type hooks).@{b} RESULT@{ub} hook - Pointer to the newly allocated XMHook structure, or NULL for failure.@{b} SEE ALSO@{ub} @{"xmRemHook()" LINK "xmRemHook"}, @{"xmIdentifyModule()" LINK "xmIdentifyModule"}, xmLoadSong(), xmSaveSong() @ENDNODE @NODE "xmAddInstrumentA" "xmodule/xmAddInstrumentA()" @{b} NAME@{ub} xmAddInstrumentA -- Adds a instrument to a song xmAddInstrument -- Varargs stub for xmAddInstrumentA@{b} SYNOPSIS@{ub} instrument = xmAddInstrumentA(si, instrNum, tagList) D0 A0 D0 A1 @{"struct Instrument" LINK "songclass.h/File" 183} *xmAddInstrumentA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG, struct TagItem *); instrument = xmAddInstrument(si,instrNum,tag1,...) @{"struct Instrument" LINK "songclass.h/File" 183} *xmAddInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG,...);@{b} FUNCTION@{ub} Adds an instrument to a song by calling the @{"SNGM_ADDINSTRUMENT" LINK "songclass.h/File" 32} method .@{b} INPUTS@{ub} si - pointer to the song to which the instrument should be added. tagList - optional TagList. See @{"SNGM_ADDINSTRUMENT" LINK "songclass.h/File" 32} for possible tags .@{b} RESULT@{ub} Pointer to the new instrument or NULL for failure.@{b} NOTE@{ub} In order to add instruments, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmRemInstrument()" LINK "xmRemInstrument"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMINSTRUMENT @ENDNODE @NODE "xmAddPatternA" "xmodule/xmAddPatternA()" @{b} NAME@{ub} xmAddPatternA -- Adds a pattern to a song xmAddPattern -- Varargs stub for xmAddPatternA@{b} SYNOPSIS@{ub} pattern = xmAddPatternA(si, tagList) D0 A0 A1 @{"struct Pattern" LINK "songclass.h/File" 229} *xmAddPatternA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,struct TagItem *); pattern = xmAddPattern (si,tag1,...) @{"struct Pattern" LINK "songclass.h/File" 229} *xmAddPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG Tag1,...);@{b} FUNCTION@{ub} Adds a pattern to a song by calling the @{"SNGM_ADDPATTERN" LINK "songclass.h/File" 29} method.@{b} INPUTS@{ub} si - pointer to the song to which the pattern should be added. tagList - optional TagList. See @{"SNGM_ADDPATTERN" LINK "songclass.h/File" 29} for possible tags.@{b} RESULT@{ub} Pointer to the new pattern or NULL for failure.@{b} NOTE@{ub} In order to add patterns, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmRemPattern()" LINK "xmRemPattern"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_ADDPATTERN @ENDNODE @NODE "xmAddSongA" "xmodule/xmAddSongA()" @{b} NAME@{ub} xmAddSongA -- Add a song to the song list xmAddSong -- Varargs stub for xmAddSongA@{b} SYNOPSIS@{ub} success = xmAddSongA(songInfo,position,tagList); D0 A0 A1 A2 ULONG xmAddSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,@{"struct SongInfo" LINK "songclass.h/File" 284} *, struct TagItem *); success = xmAddSong(songInfo,position,tag1,...); ULONG xmAddSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *,@{"struct SongInfo" LINK "songclass.h/File" 284} *, LONG,...);@{b} FUNCTION@{ub} Adds a song to the public song list. Trying to add a song twice is harmless.@{b} INPUTS@{ub} songInfo - song to be added. Passing a NULL pointer is safe. position - Position to add the song in. Passing NULL adds the song in the head of the list, while ~0 adds it in the tail. passing a pointer to a SongInfo already in the list inserts the first song _after_ the other one. tagList - pointer to a TagList for more arguments.@{b} TAGS@{ub} @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. The default is to just add the song without activating it.@{b} RESULT@{ub} success - Will be 0 for failure, in which case the song will not be added to the songs list. Currently, xmAddSongA() will never fail.@{b} NOTE@{ub} The song list is protected from multiple tasks access by a SignalSemaphore in XModuleBase. This call will wait if the song list has been locked by another task. Beware of deadlock conditions!@{b} SEE ALSO@{ub} @{"xmRemSong()" LINK "xmRemSong"} @ENDNODE @NODE "xmCreateSong" "xmodule/xmCreateSong()" @{b} NAME@{ub} xmCreateSongA -- Create and initialize a new SongInfo structure xmCreateSong -- Varargs stub for xmCreateSongA@{b} SYNOPSIS@{ub} songInfo = xmCreateSongA(tagList); D0 A0 @{"struct SongInfo" LINK "songclass.h/File" 284} *xmCreateSongA(struct TagItem *); songInfo = xmCreateSong(Tag1,...); @{"struct SongInfo" LINK "songclass.h/File" 284} *xmCreateSong(ULONG,...);@{b} FUNCTION@{ub} Allocates and initializes a new SongInfo structure. The song can then be added to the song list via @{"xmAddSongA()" LINK "xmAddSongA"}, in which case, it is no longer required to free it with @{"xmDeleteSong()" LINK "xmDeleteSong"}.@{b} INPUTS@{ub} tagList - pointer to an optional tag list specifying how to initialize the SongInfo structure.@{b} TAGS@{ub} @{"SNGA_DefaultTracks" LINK "songclass.h/File" 121} - Sets the default number of pattern tracks for the song. Defaults to 4. @{"SNGA_DefaultPattLen" LINK "songclass.h/File" 122} - Sets the default number of pattern lines for the song. Defaults to 64. @{"SNGA_ReadyToUse" LINK "songclass.h/File" 127} - Adds one pattern and one position to the song. Defaults to FALSE. @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) Add the song to the song list. When a song is being added to the list, a shared lock is obtained on it to prevent other tasks from modifying (or even remove) the song before you can do your job on it. IT IS YOUR DUTY TO UNLOCK THE SONG as soon as you are done modifying it. Passing NULL adds the song on the head of the list, while -1 (~0) will add it to the end of the SongList. Passing in a pointer to another song which is already in the list, will add the new song _after_ the latter. (Default is not adding the song). @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. This tag is considered only if the @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} tag is also passed.@{b} RESULT@{ub} songInfo - pointer to the newly allocated SongInfo structure, or NULL for failure.@{b} SEE ALSO@{ub} @{"xmDeleteSong()" LINK "xmDeleteSong"}, @{"xmAddSongA()" LINK "xmAddSongA"} @ENDNODE @NODE "xmDeleteSong" "xmodule/xmDeleteSong()" @{b} NAME@{ub} xmDeleteSong -- Deletes a song@{b} SYNOPSIS@{ub} xmDeleteSong(songInfo) A0 void xmDeleteSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b} FUNCTION@{ub} Deletes a song and all the items attached to it (patterns, instruments, etc.). This call will also remove the song from the song list if it had been added to it.@{b} INPUTS@{ub} songInfo - pointer to the SongInfo structure to be deleted. Passing a NULL pointer is harmless.@{b} NOTE@{ub} In order to delete a song which has been added to the public song list, you must first obtain an exclusive lock on it to prevent other tasks from walking on it while you are freeing it's data structures. The semaphore does NOT need to be relinquished, because the SongInfo structure won't exist any more when this call returns.@{b} SEE ALSO@{ub} @{"xmCreateSong()" LINK "xmCreateSong"}, @{"xmRemSong()" LINK "xmRemSong"} @ENDNODE @NODE "xmDisplayMessage" "xmodule/xmDisplayMessage()" @{b} NAME@{ub} xmDisplayMessageA -- Displays a message to the user xmDisplayMessage -- Varargs stub for xmDisplayMessageA()@{b} SYNOPSIS@{ub} xmDisplayMessageA(level, message, args) DO A0 A1 void xmDisplayMessageA(ULONG,APTR,LONG *); xmDisplayMessage(level, message, ...) void xmDisplayMessage(ULONG,APTR,...);@{b} FUNCTION@{ub} Outputs a string in the XModule log window or in the 'action' field of the progress indicator. The string is printf-formatted before being output.@{b} INPUTS@{ub} level - a number from 0 to 7 which indicates the importance of the message. 7 is used for very annoying messages (eg: debug output) , 0 for very important things (eg: disaster). If you set the @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187} bit in the level parameter, you can pass a catalog string number instead of a pointer to a string . Specifying @{"XMDMF_ACTION" LINK "xmodule.h/File" 185}, the message will be put in the 'action' field of the progress indicator. If the flag @{"XMDMF_DOSFAULT" LINK "xmodule.h/File" 184} is specified, a Fault() output is formatted using the message as an header. In this case, the level parameter takes another meaing: The lower word can contain an AmigaDOS error code. If it is 0, IoErr() will be used to get the error code. message - pointer to a string or catalog message number, when the @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187} flag is set. args - arguments for formatting.@{b} EXAMPLES@{ub} xmDisplayMessage (@{"XMDMF_ALERT" LINK "xmodule.h/File" 173}, "The application `%s' fucked up Windoze95 because %s.", "(unknown name)", "an error occurred"); xmDisplayMessage (XMDMF_USE_CATALOG | @{"XMDMF_COMMENT" LINK "xmodule.h/File" 179}, MSG_LIFE_UNIVERSE_AND_ALLTHAT, 42, "Fortytwo", "For tea too"); xmDisplayMessageA (@{"XMDMF_ACTION" LINK "xmodule.h/File" 185} | @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187}, MSG_READING_COMICS, NULL); xmDisplayMessage (@{"XMDMF_DOSFAULT" LINK "xmodule.h/File" 184} | @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187}, MSG_CANT_LOAD_MODULE, ModuleName);@{b} SEE ALSO@{ub} @{"xmDisplayProgress()" LINK "xmDisplayProgress"} @ENDNODE @NODE "xmDisplayProgress" "xmodule/xmDisplayProgress()" @{b} NAME@{ub} xmDisplayProgress -- Uptdates the progress bar indicator@{b} SYNOPSIS@{ub} abort = xmDisplayProgress(done, total) D0 D1 LONG @{"xmDisplayMessageA" LINK "xmDisplayMessage"}(ULONG,ULONG);@{b} FUNCTION@{ub} Updates the position of the fuel gauge in the progress window to show the progress of an operation. Additionally, it checks for user abort.@{b} INPUTS@{ub} done - a number which indicates how much of the work has been already completed total - Total number of operations to do.@{b} RESULT@{ub} 0 for success, ERROR_BREAK if user abort was detected. You should always check this return code to abort what you were doing. @ENDNODE @NODE "xmIdentifyModule" "xmodule/xmIdentifyModule()" @{b} NAME@{ub} xmIdentifyModule -- Returns the type of a module@{b} SYNOPSIS@{ub} loader = xmIdentifyModule(fh, tagList) D0 D0 A0 @{"struct XMHook" LINK "xmodule.h/File" 92} *xmIdentifyModule(BPTR,struct TagItem *);@{b} FUNCTION@{ub} Finds out a loader which is able to read the given module.@{b} INPUTS@{ub} fh - AmigaDOS FileHandle to examine. tagList - Additional parameters. Leave it NULL for now.@{b} RESULT@{ub} loader - Pointer to the first loader which knows how to load this module, or NULL otherwise.@{b} NOTE@{ub} Before you call this function, you must first obtain a lock on the loaders list to protect yourself from other tasks which might remove the returned loader before you can actually use it.@{b} SEE ALSO@{ub} @ENDNODE @NODE "xmLoadModuleA" "xmodule/xmLoadModuleA()" @{b} NAME@{ub} xmLoadModuleA -- Loads a module and converts it in XModule format xmLoadModule -- Varargs stub for xmLoadModuleA@{b} SYNOPSIS@{ub} songInfo = xmLoadModuleA(fileName,tagList) D0 A0 A1 @{"struct SongInfo" LINK "songclass.h/File" 284} *xmLoadModuleA(STRPTR,struct TagItem *); songInfo = xmLoadModule(fileName,tag,...) @{"struct SongInfo" LINK "songclass.h/File" 284} *xmLoadModule(STRPTR,LONG,...);@{b} FUNCTION@{ub} Loads fileName using the correct module loader.@{b} INPUTS@{ub} fileName - File to read. Can be NULL if the @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208} tag is passed. tagList - Additional parameters (see below). Can be NULL.@{b} TAGS@{ub} @{"XMSNG_OldSong" LINK "xmodule.h/File" 206} - ti_Data is the pointer to a SongInfo which will be freed as soon as the module format has been determined. This is useful when the user wants to replace a song with another one. Passing NULL uses the currently active song. @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) Add the song to the song list. When a song is being added to the list, a shared lock is obtained on it to prevent other tasks from modifying (or even remove) the song before you can do your job on it. IT IS YOUR DUTY TO UNLOCK THE SONG as soon as you are done modifying it. Passing NULL adds the song on the head of the list, while -1 (~0) will add it to the end of the SongList. Passing in a pointer to another song which is already in the list, will add the new song _after_ the latter. (Default is not adding the song). @{"XMSNG_Loader" LINK "xmodule.h/File" 207} - (@{"struct XMHook" LINK "xmodule.h/File" 92} *) Disables automatic format checking and forces loading the module with the given loader. (Defaults to NULL). @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208} - (BPTR) pointer to an open AmigaDOS FileHandle to read the module from. The file must already be positioned over the beginning of the module data. NOTE: Even if this tag is passed, the fileName parameter is still used to fill in the SongName field in case it is missing inside the module AND the filesystem does not support the ACTION_EXAMINE_FH packet. NOTE: Some loaders may require a fully seekable file, so be careful when using pipes. NOTE: automatic data decompression is not possible when @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208} is passed. (Defaults to NULL). XMSNG_IFFHandle - (BPTR) pointer to an already initialized IFFHandle to read the module from. The IFF must already be positioned over the beginning of the module FORM. Even if this tag is passed, the fileName parameter is still used to fill in the SongName field in case it is missing inside the module. NOTE: The iffparse.library can deal with non-seekable files, but some loaders may require a fully seekable file, so be careful when using pipes. NOTE: automatic file decompression is not possible when XMSNG_IFFHandle is passed. (Defaults to NULL). @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. This tag is considered only if the @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} tag is also passed.@{b} RESULT@{ub} songInfo - Pointer to the newly allocated SongInfo structure, or NULL for failure. This function will not fail if the module is partially corrupted. Anyway, the returned SongInfo will always be valid. You can check IoErr() to know if there were problems.@{b} EXAMPLE@{ub} /* Load a song and add it to the SongList */ si = xmLoadSongTags (file, NULL, @{"XMSNG_AddToList" LINK "xmodule.h/File" 205}, (@{"struct SongInfo" LINK "songclass.h/File" 284} *)~0, TAG_DONE); /* Check for errors even if si is not NULL */ error = IoErr(); /* Release Semaphore got by xmLoadSong() */ if (si) ReleaseSemaphore (&si->Lock);@{b} SEE ALSO@{ub} @{"xmAddSongA()" LINK "xmAddSongA"}, @{"xmIdentifyModule()" LINK "xmIdentifyModule"} @ENDNODE @NODE "xmLockActiveSong" "xmodule/xmLockActiveSong()" @{b} NAME@{ub} xmLockActiveSong -- Obtains an lock on the active song@{b} SYNOPSIS@{ub} song = xmLockActiveSong(mode); D0 D0:16 @{"struct SongInfo" LINK "songclass.h/File" 284} *@{"xmActivateSong" LINK "xmActivateSong"}(UWORD);@{b} FUNCTION@{ub} Obtains an exclusive or shared lock on the active song, waiting if needed. This call is a shortcut to: ObtainSemaphoreShared (&XModuleBase->xm_BaseLock); ObtainSemaphore[Shared] (&XModuleBase->xm_CurrentSong.Lock); ReleaseSemaphore (&XModuleBase->xm_BaseLock); To unlock a song obtained in this way, you just need to ReleaseSemaphore() it. You MUST always lock a song before you even think to read from -or write to- its data!@{b} INPUTS@{ub} mode - one of SM_SHARED or SM_EXCLUSIVE.@{b} RESULT@{ub} song - Pointer to the song which *was* active at the time you called xmLockActiveSong(). The song will be locked for you. The result will be NULL if no song is active.@{b} NOTE@{ub} Please be careful if you call this function while holding locks on other songs. Doing so, you run the risk of causing deadlock condition. This function does only lock the song; it is NOT guaranteed that it will remain the active one.@{b} SEE ALSO@{ub} @ENDNODE @NODE "xmProcessSongA" "xmodule/xmProcessSongA()" @{b} NAME@{ub} xmProcessSongA -- Performs complex processing on a song xmProcessSong -- Varargs stub for xmProcessSongA()@{b} SYNOPSIS@{ub} result = xmProcessSongA(si, reserved, tagList) A0 A1, A2 LONG xmProcessSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,void *,struct TagItem *); result = xmProcessSong(si, reserved, tag1, ...) LONG xmProcessSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,void *,LONG,...);@{b} FUNCTION@{ub} Performs complex processing operations on a song.@{b} INPUTS@{ub} si - pointer to the song to be processed. reserved - Reserved for future use. tagList - List of arguments. See below for possible tags.@{b} RESULT@{ub} The result depends on the kind of operation done. For most operations, it's value will be 0 to indicate success and an AmigaDOS error code which indicates the cause for failure.@{b} TAGS@{ub} @{"XMSNG_Optimize" LINK "xmodule.h/File" 213} - (LONG). Tries to reduce the song size by removing all unused data. Possible optimizations are: - @{"XMOF_REM_UNUSED_PATTERNS" LINK "xmodule.h/File" 221} - @{"XMOF_REM_DUP_PATTERNS" LINK "xmodule.h/File" 222} - @{"XMOF_CUT_PATTERNS" LINK "xmodule.h/File" 227} - @{"XMOF_REM_UNUSED_INSTRS" LINK "xmodule.h/File" 223} - @{"XMOF_CUT_INSTR_LOOPS" LINK "xmodule.h/File" 225} - @{"XMOF_CUT_INSTR_TAILS" LINK "xmodule.h/File" 226} - @{"XMOF_DEFAULT" LINK "xmodule.h/File" 220} @{"XMOF_DEFAULT" LINK "xmodule.h/File" 220} will select all the optimizations choosen by the user in addition to the ones specified with the other flags. @{"XMSNG_RemapInstruments" LINK "xmodule.h/File" 214} - (BOOL) Performs instruments remapping. @{"XMSNG_LimitPatterns" LINK "xmodule.h/File" 215} - (UWORD,UWORD) Limits the length all the patterns inside a minimum and maximum value. The upper 16bits of the argument are the minimum value, the lower ones are the maximum value. Patterns outside this limits will be grown or split as appropriate. @{"XMSNG_Join" LINK "xmodule.h/File" 216} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) - Joins the song with another one. @{"XMSNG_Merge" LINK "xmodule.h/File" 217} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) - Merges the song with another one.@{b} NOTE@{ub} In order to process a song, you should have exclusive access to it. Always obtain a lock before you call this function on public songs. @ENDNODE @NODE "xmRemHook" "xmodule/xmRemHook()" @{b} NAME@{ub} xmRemHook -- Removes an XModule Hook@{b} SYNOPSIS@{ub} xmRemHookA(xmHook) A0 void xmRemHook(@{"struct XMHook" LINK "xmodule.h/File" 92} *);@{b} FUNCTION@{ub} Removes an XModule Hook, calls its RemoveHookFunc() and then frees its memory.@{b} INPUTS@{ub} xmHook - pointer to the hook to be removed.@{b} SEE ALSO@{ub} @{"xmAddHook()" LINK "xmAddHook"} @ENDNODE @NODE "xmRemInstrument" "xmodule/xmRemInstrument()" @{b} NAME@{ub} xmRemInstrument -- Removes an instrument from a song@{b} SYNOPSIS@{ub} xmRemInstrument(si, instrNum) A0 D0 void xmRemInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG);@{b} FUNCTION@{ub} Removes an instrument from a song by calling the @{"SNGM_REMINSTRUMENT" LINK "songclass.h/File" 34} method.@{b} INPUTS@{ub} si - pointer to the song to which the instrument should be removed. mum - Number of the instrument to be removed.@{b} NOTE@{ub} In order to remove instruments, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmAddInstrumentA()" LINK "xmAddInstrumentA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMINSTRUMENT @ENDNODE @NODE "xmRemPattern" "xmodule/xmRemPattern()" @{b} NAME@{ub} xmRemPattern -- Removes a pattern from a song@{b} SYNOPSIS@{ub} xmRemPattern(si, pattNum, replaceWith) A0 D0, D1 void xmRemPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG);@{b} FUNCTION@{ub} Removes a pattern from a song by calling the @{"SNGM_REMPATTERN" LINK "songclass.h/File" 31} method.@{b} INPUTS@{ub} si - pointer to the song to which the pattern should be removed. mum - Number of the pattern to be removed. replaceWith - What to put in the song sequence in place of the deleted pattern.@{b} NOTE@{ub} In order to remove patterns, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmAddPatternA()" LINK "xmAddPatternA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMPATTERN @ENDNODE @NODE "xmRemSong" "xmodule/xmRemSong()" @{b} NAME@{ub} xmRemSong -- Remove a song from the song list@{b} SYNOPSIS@{ub} success = xmRemSong(songInfo); D0 A0 ULONG xmRemSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b} FUNCTION@{ub} Removes a song from the public song list. It is safe to call this function even if the song has not been added to the song list. If the passed SongInfo is the active one, another song will be selected automatically.@{b} INPUTS@{ub} songInfo - song to be removed. If NULL, this function will take no action.@{b} RESULT@{ub} success - Will be 0 for failure, in which case the song will not be removed from the song list. Currently, xmRemSong() will never fail.@{b} NOTE@{ub} In order to remove a song, you must first obtain an exclusive lock on it. The song list is also protected from multiple task access by a SignalSemaphore. This call will wait if the song list has been locked by another task. Beware of deadlock conditions!@{b} SEE ALSO@{ub} @{"xmAddSongA()" LINK "xmAddSongA"} @ENDNODE @NODE "xmSaveModuleA" "xmodule/xmSaveModuleA()" @{b} NAME@{ub} xmSaveModuleA -- Saves a module to the specified file format xmSaveModule -- Varargs stub for xmSaveModuleA@{b} SYNOPSIS@{ub} error = xmSaveModuleA(songInfo, fileName, saver, tagList) D0 A0 A1 A2 A3 LONG xmSaveModuleA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,STRPTR,@{"struct XMHook" LINK "xmodule.h/File" 92} *, struct TagItem *); error = xmSaveModule(songInfo, fileName, saver, tag1,...) LONG xmSaveModule(@{"struct SongInfo" LINK "songclass.h/File" 284} *,STRPTR,@{"struct XMHook" LINK "xmodule.h/File" 92} *, LONG,...);@{b} FUNCTION@{ub} Saves songInfo to fileName using the specified saver.@{b} INPUTS@{ub} songInfo - Song to save. fileName - AmigaDOS filename to write the song to. saver - Pointer to the saver to use. Pass NULL to use the default saver.@{b} TAGS@{ub} No tags are defined for this call.@{b} RESULT@{ub} error - RETURN_OK for success, or any other AmigaDOS error code to mean failure. In particular, RETURN_WARN indicates that something went wrong, but the song is still ok. The special error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} means that some dos.library call (e.g.: Read()) failed. In the latter case, the AmigaDOS IoErr() value will be set to explain the specific cause of the problem.@{b} SEE ALSO@{ub} @ENDNODE @NODE "xmSetInstrumentA" "xmodule/xmSetInstrumentA()" @{b} NAME@{ub} xmSetInstrumentA -- Sets an instrument's attributes xmSetInstrument -- Varargs stub for xmSetInstrumentA@{b} SYNOPSIS@{ub} success = xmSetInstrumentA(si, instrNum, tagList) D0 A0 D0 A1 ULONG xmSetInstrumentA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG, struct TagItem *); success = xmSetInstrument(si,instrNum,tag1,...) ULONG xmSetInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG,...);@{b} FUNCTION@{ub} Sets an instrument's attributes by calling the @{"SNGM_SETINSTRUMENT" LINK "songclass.h/File" 33} method.@{b} INPUTS@{ub} si - pointer to the song which contains the instrument to be set. tagList - instrument attributes to set. See @{"SNGM_SETINSTRUMENT" LINK "songclass.h/File" 33} for possible tags.@{b} RESULT@{ub} non zero for success.@{b} NOTE@{ub} In order to set instruments' attributes, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmAddInstrument()" LINK "xmAddInstrumentA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_SETINSTRUMENT @ENDNODE @NODE "xmSetPatternA" "xmodule/xmSetPatternA()" @{b} NAME@{ub} xmSetPatternA -- Sets pattern attributes xmSetPattern -- Varargs stub for xmSetPatternA@{b} SYNOPSIS@{ub} success = xmSetPatternA(si, pattNum, tagList) D0 A0 D0 A1 ULONG xmSetPatternA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,ULONG,struct TagItem *); success = xmSetPattern (si,pattNum,tag1,...) ULONG xmSetPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,ULONG,LONG Tag1,...);@{b} FUNCTION@{ub} Sets attributes of a pattern by calling the @{"SNGM_SETPATTERN" LINK "songclass.h/File" 30} method.@{b} INPUTS@{ub} si - pointer to the song which contains the pattern to be set. tagList - list of attributes to set. See @{"SNGM_SETPATTERN" LINK "songclass.h/File" 30} for possible tags.@{b} RESULT@{ub} Non zero for success@{b} NOTE@{ub} In order to set patterns attributes, you should have exclusive access to the song. Always obtain a lock before you call this function on public songs.@{b} SEE ALSO@{ub} @{"xmAddPattern()" LINK "xmAddPatternA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_SETPATTERN @ENDNODE @NODE "xmSetSongLen" "xmodule/xmSetSongLen()" @{b} NAME@{ub} xmSetSongLen -- Set the number of song positions@{b} SYNOPSIS@{ub} sequence = xmSetSongLen(songInfo, length) D0 A0 D0:16 UWORD *xmSetSongLen(@{"struct SongInfo" LINK "songclass.h/File" 284} *, UWORD);@{b} FUNCTION@{ub} Allocates space in the song for a sequence table of the given length. If no sequence exists yet, a new one is allocated. Increasing the song length may require the sequence table to be expanded, in which case it will be re-allocated and the old sequence entries will be copied. Decreasing the song length could also cause a reallocation of the sequence table if the size drops down enough. Setting the song length to 0 will free the sequence table and return NULL.@{b} INPUTS@{ub} songInfo - pointer to a SongInfo structure. length - new length of song sequence table.@{b} NOTE@{ub} This function will also adjust the CurrentPos field if it is found beyond the song end@{b} BUGS@{ub} This funtion is quite useless because all it does is setting the @{"SNGA_Length" LINK "songclass.h/File" 88} attribute in the song object. Setting the @{"SNGA_Length" LINK "songclass.h/File" 88} attribute yourself is easier and faster if you are already setting other attributes in the same song.@{b} RESULT@{ub} Pointer to the newly allocated sequence table or NULL for failure, in which case the previous sequence table is left untouched. @ENDNODE