In an effort to help clarify the Input SDK , I have written the following description of how to write an input plugin. (JRiver you may use this in future versions if you think it's worthwhile.) This description assumes MS Visual C++ .NET 2003. It's actually fairly similar to creating an interface plugin since they are both MFC COM components.
1. Create a new project by clicking File->New->Project. You will be creating an MFC DLL project. Give the project a name like "in_flac" or "in_wav". For the purposes of this writeup, I'll assume it's "in_flac". Make the DLL a static link to MFC since the MFC DLLs are not distributed with MC. This is a "Regular DLL using static link to MFC DLL". You do not need to include Automation or Windows Sockets.
2. In the project properties (right click on "in_flac"), make a few changes:
- Under Properties->General change the character set from Multi-Byte to Unicode.
- Under Linker->Input, remove the module definition file.
3. Remove the in_flac.cpp/.h/.def files from the project and the project directory. They aren't needed.
4. Add an include directory (right click on the project, then Properties, then C/C++ and General). Add the directory to the Input SDK to the "Additional Include Directories".
5. Add the following files from the Input SDK to the project. You can copy them directly into the project directory if you prefer, in which case you don't need to add the directory in step 4. Add to the project by right clicking the project, then Add->Add Existing Item.
- MJInputSource.cpp
- MJInputSource.h
- MJFields.h
- GeneralReader.h
6. Using the Add Class function (right click on the project, then Add->Add Class), add the two classes below. Use the "Generic C++ Class". The class files are *.h/*.cpp by default, which is fine. Both are public access.
- InputSource, based on CMJInputSource
- FileInfo, based on CMJFileInfo
7. Export the two new classes so that MC can grab them from the DLL. To do this you use code like this for InputSource:
// Exported function for instance creation
extern "C"
{
__declspec (dllexport) CMJInputSource *GetInputSource()
{
return new InputSource;
}
}
And like this for FileInfo:
// Exported function for MC instance creation
extern "C"
{
__declspec (dllexport) int GetFileInfo(HINSTANCE hDllInstance, CMJFileInfo **classFileInfo) {
// Return 0 on Failure
*classFileInfo = (CMJFileInfo *) new FileInfo;
return 1;
}
}
8. Now comes the hard part. For the InputSource class, you will now need to implement, at a minimum, the following functions. You should refer to the SDK example (MJRAWInputSource) and the base class MJInputSource for guidance. You can get a pretty good start by simply copying the default functions from the base class.
- Open(...)
- GetInformation(...)
- SetInformation(...)
- DoCommand(...)
- AddDataToBuffer()
Be sure to set the following variables:
- m_nTotalSampleBufferBytes
- m_nLengthMS
- m_nLengthBlocks
9. For the FileInfo class, you will need to implement, at a minimum, the following functions.
- GetAttribute(...)
- SetAttribute(...)
- GetFormatString(...)
- Open(...)
- Close()
- DoCommand(...)
10. How it works. The InputSource interface is used when decoding (playing or burning) the compressed file to wav data. It's pretty straight forward in the sense that all MC does is pass the name of the file to the Open function, and then start calling AddDataToBuffer over and over until either you finish the file, the user presses stop (or next, etc), or a seek happens. Only one InputSource interface will be opened for each file.
The FileInfo interface is used for tagging and basic format information. Multiple interfaces to the same file can be opened in rapid succession. Each time you will get an Open and a Close called. What happens in-between depends on what the user is doing (File Type Info, updating tags to library, etc.).
[Edits]
1. Modified for static link to MFC.
2. Modified for Generic C++ Class.