How to create and use APlayer converters


Overview

This document will tell you how to create and how to use APlayer converters. A converter is almost like the other add-ons APlayer supports. If you haven't read about them yet, it's strongly recommented you do this first. You can read about them here.

A converter is an add-on that can either load, save or both samples. Examples on such converters is the AudioIFF and RIFF-WAVE converters. The converters are used in e.g. the Sample Info agent and the Sample player.


How to create a converter

To create a converter, you do the same thing as when creating one of the other add-ons, by having the Load(), Unload() and GetInstance() functions. There is one difference, and that is the GetInstance() function need to return a pointer to a APAddOnConverter instead of a APAddOn.

You need to create your own class, which derives from APAddOnConverter. In this class there is some virtual functions you need and/or can override if you want. These functions are e.g. loader and saver functions. If you only want to create a loader, you only need to override the loader functions.

The next 3 sections is splitted depending on the functions you can override. The first section is about the independent functions. These functions can be overriden when you create a loader or a saver. The next section is about the loader functions. Only override these if you create a loader. And finally the last section is about the saver function. Only override these functions if you create a saver.


Independent virtual functions


GetDescription()

          virtual PString GetDescription(void);

This function has to return a description of your converter. The description will be shown in the settings window, so the user can see what the converter does, but only if the Sample player is installed and your converter support loading. If you only support saving of samples, you don't need this function.


GetExtension()

          virtual PString GetExtension(void) = 0;

You has to override this function. It has to return the file extension of the sample format you support. This extension can e.g. be .aiff or .wav. Remember the dot in the beginning of the string.


GetName()

          virtual PString GetName(void) = 0;

You has to override this function. It has to return the name of your converter. This name is used to indentify your converter. Call your converter the name of the format you support, e.g. AudioIFF or RIFF-WAVE.


GetSupportFlags()

          virtual uint32 GetSupportFlags(void) = 0;

This function has to return some flags that indicates what your converter supports. This can be if your converter support saving or not. Below is a table over the different flags. Every flag can be or'ed together.

Converter flags:

 Name  Description
 apcLoader  Set this flag if your converter can load samples.
 apcSaver  Set this flag if your converter can save samples.


GetTypeString()

          virtual PString GetTypeString(void);

This function has to return the type of the sample format. On BeOS, this is the mime-type string, e.g. audio/x-aiff.


GetVersion()

          virtual float GetVersion(void);

Override this function if you have a version. The function has to return the version as a floating point number. The default implementation returns 0.0.


Loader virtual functions


FileCheck()

          virtual ap_result FileCheck(PFile *file);

This function has to check the file given as the argument, to see if it's the supported sample type. If it is, return AP_OK, else return AP_UNKNOWN.


GetInfoCount()

          virtual uint32 GetInfoCount(void);

This function is just like the GetInfoCount() in the APAddOnPlayer class. It returns the number of extra lines you want to be showed in the module info window. The function is called from e.g. the Sample player. Use this function together with the GetInfoString() function.


GetInfoString()

          virtual PString GetInfoString(uint32 line, ap_infoType type);

This function is just like the GetInfoString() in the APAddOnPlayer class. It returns the string for the line given. The string can either be the description or value. See GetInfoString() for more information.


GetTotalSampleLength()

          virtual uint32 GetTotalSampleLength(const ConvertInfo *convInfo);

This function returns the total number of samples that will be returned. Notice that it's in samples, not bytes. If the file is a stereo file, each channel is counted as 2 samples. An example is if the file is 1000 bytes long and it's in 16-bit stereo. You then need to return: 1000 / 2 = 500 and not 1000 / 2 / 2 = 250. The number 500 is the right result.


LoadData()

          virtual uint32 LoadData(PFile *file, float *buffer, uint32 length, const ConvertInfo *convInfo);

This function loads some of the sample data from the file given. You are given a pointer to a buffer to fill and the length of it in samples. You need to convert the samples you read to floating points. Each sample is in the range from -1.0 to +1.0. You are also given a ConvertInfo structure, where you can read the information needed to read the samples. This function can be called multiple times.

If you can't fill the whole buffer, because you're out of data, just fill out as much as you can. Just remember, you may not fill more data in the buffer than the length given. The function returns the number of samples filled in the buffer. If you ran to the EOF mark, return 0, which indicates to the loader, that there isn't more data to read.


LoaderEnd()

          virtual void LoaderEnd(void);

This function is called at the end of the loader. It should clean up anything you have initialized in the LoaderInit() function. This is e.g. free the memory buffers you have alloacated.


LoaderInit()

          virtual bool LoaderInit(void);

This function should initialize your converter, so it's ready to be used. In this function, you probably initialize some class variables to default values or allocate some memory buffers. Return true for success or false if you want to stop the loader. Remember to show an error message to the user.


LoaderView()

          virtual BView *LoaderView(void);

If your converter have a loader settings window, you can override this function. A loader settings window is a window that has to be shown to the user just before the sample data is loaded, but after the header. You can then show some information to the user, maybe let the user change some of them. This can e.g. be used to a raw sample file loader, where the user can select the format of the sample, e.g. little or big endian and 8 or 16 bit.

You need to return a pointer to a BView holding all your views as siblings. The pointer has to be new'ed, because APlayer delete it after use. If you return NULL, which is the default implementation, no window will be shown.


LoadHeader()

          virtual ap_result LoadHeader(PFile *file, ConvertInfo *convInfo);

This function loads the sample header from the file. The function has to fill out the ConvertInfo structure with the information it got from the header. If the function fails, return AP_ERROR, else return AP_OK. Remember to show an error message to the user.


SetSamplePosition()

          virtual ap_result SetSamplePosition(PFile *file, uint32 position, const ConvertInfo *convInfo);

This function is used to seek to the right place in the sample data in the file. The arguments is the file to seek in, the position to seek to and the ConvertInfo structure to get relevant information about the sample format. The position is in samples, not bytes. Notice that stereo samples is counted as 2 samples.

Return AP_ERROR if something failed, AP_OK if everything is alright. Remember to show an error message to the user.


Saver virtual functions


SaverEnd()

          virtual void SaverEnd(void);

This function is called at the end of the saver. It should clean up anything you have initialized in the SaverInit() function. This is e.g. free the memory buffers you have alloacated.


SaverInit()

          virtual bool SaverInit(void);

This function should initialize your converter, so it's ready to be used. In this function, you probably initialize some class variables to default values or allocate some memory buffers. Return true for success or false if you want to stop the saver. Remember to show an error message to the user.


SaverView()

          virtual BView *SaverView(void);

If your converter have a saver settings window, you can override this function. A saver settings window is a window that has to be shown to the user just before any data is written to the file. An example of a saver settings window, is if your sample format support sample packing. The user can then select how much the samples should be compressed.

You need to return a pointer to a BView holding all your views as siblings. The pointer has to be new'ed, because APlayer delete it after use. If you return NULL, which is the default implementation, no window will be shown.


SaveData()

          virtual ap_result SaveData(PFile *file, const float *buffer, uint32 length, const ConvertInfo *convInfo);

This function saves the sample data given to the file. You are given a pointer to a buffer with the sample data and the length of it in samples. You need to convert the samples from floating points to the format you want to write in the file. Each sample is in the range from -1.0 to +1.0. You are also given a ConvertInfo structure, where you can read the information needed to write the samples. This function can be called multiple times.

Return AP_OK for success or AP_ERROR for failure. Remember to show an error message to the user.


SaveHeader()

          virtual ap_result SaveHeader(PFile *file, const ConvertInfo *convInfo);

This function has to save the file header. You will get in the ConvertInfo structure the format of the sample that needs to be written. This can e.g. be the sample frequency and the number of bits used. If the function fails, return AP_ERROR, else return AP_OK. Remember to show an error message to the user.


SaveTail()

          virtual ap_result SaveTail(PFile *file, const ConvertInfo *convInfo);

This function is the last one called when the sample is written. You can write some extra data at the end of the file, change the header or set the mimetype on the file.

Return AP_ERROR if something failed, AP_OK if everything is alright. Remember to show an error message to the user.


How to use a converter

If you want to use a converter from another add-on, e.g. an Agent, this is where you can read about it. You can use a converter in two different ways. You can use it as a loader or as a saver. In the first section I will tell you how to use it as a saver. The next section is about the loader part. The two sections is very similary, because there isn't the big difference between the two methods.

The methods will be described step by step, telling which functions to call. You have to call the functions described in the same order if you want to be 100% sure that it work like expected. You can ofcourse put your own code between each step if you want that.

Saver

1. First of all you need to create a ConvertInfo structure and fill it out with all the informations.

2. Call the GetConverterInstance() in APGlobalData to get a pointer to the converter to use.

3. Call the GetExtension() in the converter to get the file extension and append it to the filename if not already appended.

4. Open the file with read and write access.

5. Call SaverInit() in the converter.

6. Call the ShowConverterConfig() in APGlobalData. If the function returned false, close and delete the file and stop to save data.

7. Call the SaveHeader() in the converter.

8. Call the SaveData() in the converter the number of times needed to save all the data.

9. Call the SaveTail() in the converter.

10. Call the SaverEnd() in the converter.

11. Close the file.

12. Call the DeleteConverterInstance() in APGlobalData to delete the converter instance.

 

Loader

1. First call the GetConverterInstance() in APGlobalData to get a pointer to the converter to use.

2. Open the file with read access.

3. Call the FileCheck() in the converter. If you got a ok from this function, the converter knowns the format of the file and you can continue. Else close the file and stop loading.

4. Call LoaderInit() in the converter.

5. Call the LoadHeader() in the converter to load the file header into a ConverterInfo structure.

6. Call the ShowConverterConfig() in APGlobalData. If the function returned false, close the file and stop the loader.

7. Call the SetSamplePosition() in the converter to set the position to the start of the file or where you else want to start loading.

8. Call the LoadData() in the converter until you have read the whole file or the bit you want.

9. Call the LoaderEnd() in the converter.

11. Close the file.

12. Call the DeleteConverterInstance() in APGlobalData to delete the converter instance.


The APlayer developer documentation for APlayer 3.5.2.
This documentation was written by Thomas Neumann.
© Copyright 1998-2000 by The APlayer-Team / PolyCode.