home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 119
/
af119sub.adf
/
SamEd.lzx
/
SamEd
/
Developers
/
extproc.h
< prev
next >
Wrap
C/C++ Source or Header
|
2001-04-09
|
17KB
|
583 lines
/*name of the message port*/
#define EPMPORT_NAME "SamED_EPMPort"
/*External Processor Commands*/
/*commands always available...*/
#define EPC_VERSION 0 /* returns current version */
#define EPC_AUTOQUIT 1 /* set auto quit mode for a specific task (given a pointer to the task, and a sigbit number */
#define EPC_IDNUM 2 /* returns your (the ext. proc.) id number given a pointer to your task */
#define EPC_MULTI 3 /* set multi load mode, the given ext. proc. can be opened multiple times */
#define EPC_QUIT 4 /* tell SamEd you will quit, given your ID no. and/or task pointer */
#define EPC_TOTALNUM 5 /* ask for maximum number of samples */
/*lock commands...*/
#define EPC_LOCK 6 /* set lock, required to alter data and/or to safely read data*/
#define EPC_UNLOCK 7 /* unlock lock */
/*commands requiring you to hold the lock to the system...*/
#define EPC_GETSAMPLE 8 /* get pointer to current sam_info structure */
#define EPC_GETSAMPLES 9 /* get pointer to array of all sam_info structs */
#define EPC_GETBUFFER 10 /* get pointer to sample[0] / the copy buffer */
#define EPC_GETSAMNUM 11 /* get current sample number */
#define EPC_GETRSTART 12 /* get range start */
#define EPC_GETREND 13 /* get range end */
#define EPC_SETSAMNUM 14 /* set current sample */
#define EPC_SETRSTART 15 /* set range start */
#define EPC_SETREND 16 /* set range end */
#define EPC_FLUSH 17 /* flush current sample from memory */
#define EPC_PIOPEN 19 /* open progress indicator */
#define EPC_PISTRING 20
#define EPC_PIMAX 21
#define EPC_PIVAL 22
#define EPC_PICLOSE 23
/*EPCErrors...*/
#define EPCERR_NOERR 0 /* command sucessful */
#define EPCERR_NOCOMMAND 1 /* unrecognised command */
#define EPCERR_SAMNUM 2 /* sample id number out of range */
#define EPCERR_NOAQUIT 3 /* auto quit could not be allocated */
#define EPCERR_LOCKED 4 /* returned by EPC_LOCK when system is already locked */
/*Procs magic number*/
#define PROC_MAGIC ('S'<<24 | 'E'<<16 | 'P'<<8 | 0) /*SamEd Proc version 0*/
/*Filer errors*/
#define FERR_NOERR 0 /* no error */
#define FERR_GENERAL 1 /* general error. The minimum you should return if an error occurs */
#define FERR_FILEERR 2 /* file error. General error with the actual file processing */
#define FERR_ACTIONNA 3 /* action (load / save / etc.) not supported */
#define FERR_STYPENA 4 /* sample type not supported */
#define FERR_NOTMAGIC 5 /* the 'magic number' did not match */
/*Filer actions*/
#define FACT_LOAD 1 /* load action */
#define FACT_SAVE 2 /* save action */
/*Filers magic number*/
#define FILER_MAGIC ('S'<<24 | 'E'<<16 | 'F'<<8 | 0) /*SamEd Filer version 0*/
/*structures...*/
static struct Ext_Proc_Msg{
struct Message epm_Msg;
ULONG epm_Command;
ULONG epm_Error;
APTR epm_Data;
};
static struct Ext_Proc_ID{
struct Task *task;
ULONG number;
};
static struct sam_info {
BYTE *waveform;
ULONG length;
ULONG type;
ULONG loop_begin;
ULONG loop_length;
BOOL loop;
BYTE reserved[3];
ULONG def_freq;
ULONG def_vol;
ULONG file_type;
char *dir;
char *name;
};
/*sound types, these are the same as AHI*/
#define STYPE_M8 0 /* Mono, 8 bit signed (BYTE) */
#define STYPE_M16 1 /* Mono, 16 bit signed (WORD) */
#define STYPE_M32 8 /* Mono, 32 bit signed (LONG) */
#define STYPE_S8 2 /* Stereo, 8 bit signed (2×BYTE) */
#define STYPE_S16 3 /* Stereo, 16 bit signed (2×WORD) */
#define STYPE_S32 10 /* Stereo, 32 bit signed (2×LONG) */
/*---------------------------------------------------------------------------------------------------\
| The following functions are to help with communication with SamEd. |
| define NO_EPP_HELP if you do not require them. |
\---------------------------------------------------------------------------------------------------*/
#ifndef NO_EPP_HELP
struct EP_Port {
struct MsgPort *our_mp;
struct Ext_Proc_Msg message;
ULONG button;
BOOL lock;
};
typedef struct EP_Port * EPP_HANDLE;
EPP_HANDLE EP_NewPort (ULONG);
void EP_DeletePort (EPP_HANDLE);
BOOL EP_SendMsg (EPP_HANDLE, ULONG, void *);
BOOL EP_SendIDMsg (EPP_HANDLE, ULONG, struct Task *, ULONG);
BOOL EP_Quit (EPP_HANDLE);
BYTE EP_AllocQSig (EPP_HANDLE);
void EP_DeallocQSig (BYTE);
BOOL EP_Lock (EPP_HANDLE);
BOOL EP_Unlock (EPP_HANDLE);
BOOL EP_GetSample (EPP_HANDLE, struct sam_info **, struct sam_info **, ULONG *);
EPP_HANDLE EP_NewPort (ULONG button)
{
EPP_HANDLE ep_port;
if (ep_port = AllocMem(sizeof (struct EP_Port), MEMF_CLEAR))
{
if (ep_port->our_mp = (struct MsgPort *)CreatePort(NULL,0))
{
ep_port->message.epm_Msg.mn_Node.ln_Type = NT_MESSAGE;
ep_port->message.epm_Msg.mn_ReplyPort = ep_port->our_mp;
ep_port->message.epm_Msg.mn_Length = sizeof(struct Ext_Proc_Msg);
ep_port->button = button;
ep_port->lock = FALSE;
return (ep_port);
}
else
{
FreeMem(ep_port, sizeof (struct EP_Port));
return(NULL);
}
}
else
return (NULL);
}
void EP_DeletePort (EPP_HANDLE ep_port)
{
if (ep_port->lock) EP_Unlock (ep_port);
if (ep_port)
{
if (ep_port->our_mp)
{
while(GetMsg(ep_port->our_mp));
DeletePort(ep_port->our_mp);
}
FreeMem(ep_port, sizeof (struct EP_Port));
}
}
BYTE EP_AllocQSig (EPP_HANDLE ep_port)
{
BYTE signal;
if (-1 == (signal = AllocSignal(-1)))
return(-1);
if (EP_SendIDMsg(ep_port, EPC_AUTOQUIT, FindTask(0), signal))
return(signal);
FreeSignal (signal);
return(-1);
}
void EP_DeallocQSig (BYTE signal)
{
if (signal != -1)
FreeSignal (signal);
}
BOOL EP_SendMsg (EPP_HANDLE ep_port, ULONG command, void * data)
{
printf("Try to send...\n");
struct MsgPort *dest_mp;
ep_port->message.epm_Command = command;
ep_port->message.epm_Data = data;
Forbid();
if (dest_mp = (struct MsgPort *)FindPort(EPMPORT_NAME))
PutMsg(dest_mp, (struct Message *)&ep_port->message);
Permit();
if (dest_mp)
{
printf("Sent!!!\n");
WaitPort(ep_port->our_mp);
while(GetMsg(ep_port->our_mp));
}
return (dest_mp ? TRUE : FALSE);
}
BOOL EP_SendIDMsg (EPP_HANDLE ep_port, ULONG command, struct Task * task, ULONG number)
{
struct Ext_Proc_ID id_data;
id_data.task = task;
id_data.number = number;
return (EP_SendMsg (ep_port, command, &id_data));
}
BOOL EP_Quit (EPP_HANDLE ep_port)
{
return (EP_SendIDMsg (ep_port, EPC_QUIT, FindTask(0), ep_port->button));
}
BOOL EP_Lock (EPP_HANDLE ep_port)
{
if (ep_port->lock == TRUE)
return (TRUE);
if (!EP_SendMsg (ep_port, EPC_LOCK, NULL))
return (FALSE);
if (ep_port->message.epm_Error)
return (FALSE);
ep_port->lock = TRUE;
return (TRUE);
}
BOOL EP_Unlock (EPP_HANDLE ep_port)
{
if (ep_port->lock == FALSE)
return (TRUE);
if (!EP_SendMsg (ep_port, EPC_UNLOCK, NULL))
return (FALSE);
if (ep_port->message.epm_Error)
return (FALSE);
ep_port->lock = FALSE;
return (TRUE);
}
BOOL EP_GetSample (EPP_HANDLE ep_port, struct sam_info **sample, struct sam_info **copybuf, ULONG *range)
{
BOOL sucess = TRUE, old_lock = ep_port->lock;
if (ep_port->lock == FALSE)
if (!EP_Lock (ep_port)) return(FALSE);
if (sample)
{
if (EP_SendMsg (ep_port, EPC_GETSAMPLE, NULL))
*(sample) = ep_port->message.epm_Data;
else
{*(sample) = NULL; sucess = FALSE;}
}
if (copybuf)
{
if (EP_SendMsg (ep_port, EPC_GETBUFFER, NULL))
*(copybuf) = ep_port->message.epm_Data;
else
{*(copybuf) = NULL; sucess = FALSE;}
}
if (range)
{
if(EP_SendMsg (ep_port, EPC_GETRSTART, NULL))
{
*(range++) = *((ULONG *)ep_port->message.epm_Data);
if (EP_SendMsg (ep_port, EPC_GETREND, NULL))
{
*range = *((ULONG *)ep_port->message.epm_Data);
}
else
{
*(range--) = 0;
*(range) = 0;
sucess = FALSE;
}
}
}
if (!old_lock) EP_Unlock(ep_port);
return(sucess);
}
#endif /*NO_EPP_HELP*/
/*---------------------------------------------------------------------------------------------------\
| These functions help with 8 / 16 / mono / stereo data processing. |
| 32 bit floating point versions are also included (I don't know if they work, nor do I |
| know how 32 bit fp data is supposed to be interpreted!). |
| |
| All data is changed to 16 bit resolution. |
| |
| I have estimated the Macros SET_ / GET_LEVEL to be 50% quicker than the functions |
| Set_ / Get_Level(). |
| |
| define NO_DATA_HELP to disable. |
\---------------------------------------------------------------------------------------------------*/
#ifndef NO_DATA_HELP
void Set_Level (BYTE *, ULONG, LONG, ULONG, UBYTE);
WORD Get_Level (BYTE *, ULONG, ULONG, UBYTE);
ULONG Sams_To_Bytes (ULONG, ULONG);
ULONG Bytes_To_Sams (ULONG, ULONG);
void CopyWave (BYTE *, ULONG, BYTE *, ULONG, ULONG);
void setb_lev (BYTE *, ULONG, LONG, UBYTE);
void setw_lev (BYTE *, ULONG, LONG, UBYTE);
void setl_lev (BYTE *, ULONG, LONG, UBYTE);
void setsb_lev (BYTE *, ULONG, LONG, UBYTE);
void setsw_lev (BYTE *, ULONG, LONG, UBYTE);
void setsl_lev (BYTE *, ULONG, LONG, UBYTE);
void setnon_lev (BYTE *, ULONG, LONG, UBYTE);
LONG getb_lev (BYTE *, ULONG, UBYTE);
LONG getw_lev (BYTE *, ULONG, UBYTE);
LONG getl_lev (BYTE *, ULONG, UBYTE);
LONG getsb_lev (BYTE *, ULONG, UBYTE);
LONG getsw_lev (BYTE *, ULONG, UBYTE);
LONG getsl_lev (BYTE *, ULONG, UBYTE);
LONG getnon_lev (BYTE *, ULONG, UBYTE);
static void (*Set_Level_Function[])(BYTE *, ULONG, LONG, UBYTE) = {
setb_lev,
setw_lev,
setsb_lev,
setsw_lev,
setnon_lev,
setnon_lev,
setnon_lev,
setnon_lev,
setnon_lev,
setl_lev,
setnon_lev,
setsl_lev,
};
static LONG (*Get_Level_Function[])(BYTE *, ULONG, UBYTE) = {
getb_lev,
getw_lev,
getsb_lev,
getsw_lev,
getnon_lev,
getnon_lev,
getnon_lev,
getnon_lev,
getnon_lev,
getl_lev,
getnon_lev,
getsl_lev,
};
/*Macros use 'type' to index an array of pointers to edit functions. SET_LEVELN does not clip*/
#define GET_LEVEL(start, pos, type, chan) (*Get_Level_Function[(type)])((start), (pos), (chan))
#define SET_LEVELN(start, pos, lev, type, chan) (*Set_Level_Function[(type)])((start), (pos), (lev), (chan))
#define SET_LEVEL(start, pos, lev, type, chan) LONG macro_level = lev;\
if (macro_level > 32767) macro_level = 32767;\
else if (macro_level < -32768) macro_level = -32768;\
(*Set_Level_Function[(type)])((start), (pos), macro_level, (chan))
void Set_Level(BYTE *start, ULONG pos, LONG level, ULONG type, UBYTE channel)
{
if (level > 32767) level = 32767;
else if (level < -32768) level = -32768;
switch (type)
{
case STYPE_M8:
*((BYTE *) start + pos) = level >>8;
break;
case STYPE_M16:
*((WORD *) start + pos) = level;
break;
case STYPE_M32:
*((float *) start + pos) = (float)level;
break;
case STYPE_S8:
*((BYTE *) start + (pos <<1) +channel) = level >>8;
break;
case STYPE_S16:
*((WORD *) start + (pos <<1) +channel) = level;
break;
case STYPE_S32:
*((float *) start + (pos <<1) +channel) = (float)level;
break;
}
}
WORD Get_Level(BYTE *start, ULONG pos, ULONG type, UBYTE channel)
{
switch (type)
{
case STYPE_M8: return( *(start + pos) <<8);
case STYPE_M16: return( *((WORD *)start + pos));
case STYPE_M32: return( (WORD) *((float *)start + pos));
case STYPE_S8: return( *(start + (pos <<1) +channel) <<8);
case STYPE_S16: return( *((WORD *)start + (pos <<1) +channel));
case STYPE_S32: return( (WORD) *((float *)start + (pos <<1) +channel));
}
}
ULONG Sams_To_Bytes(ULONG sams, ULONG type)
{
ULONG bytes;
switch (type)
{
case STYPE_M8:
bytes = sams;
break;
case STYPE_M16:
bytes = sams *2;
break;
case STYPE_M32:
bytes = sams *4;
break;
case STYPE_S8:
bytes = sams *2;
break;
case STYPE_S16:
bytes = sams *4;
break;
case STYPE_S32:
bytes = sams *8;
break;
}
return(bytes);
}
ULONG Bytes_To_Sams(ULONG bytes, ULONG type)
{
ULONG sams;
switch (type)
{
case STYPE_M8:
sams = bytes;
break;
case STYPE_M16:
sams = bytes /2;
break;
case STYPE_M32:
sams = bytes /4;
break;
case STYPE_S8:
sams = bytes /2;
break;
case STYPE_S16:
sams = bytes /4;
break;
case STYPE_S32:
sams = bytes /8;
break;
}
return(sams);
}
void CopyWave (BYTE *from, ULONG fromtype, BYTE *to, ULONG totype, ULONG length)
{
if (fromtype == totype)
{
length = Sams_To_Bytes (length, fromtype);
CopyMem(from, to, length);
return();
}
if (totype & 2)/*both stereo, or mono to stereo*/
{
for (ULONG n =0; n < length; n++)
{
SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 0), totype, 0);
}
for (ULONG n =0; n < length; n++)
{
SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 1), totype, 1);
}
return();
}
if (fromtype & 2)/*from stereo to mono*/
{
for (ULONG n =0; n < length; n++)
{
SET_LEVELN(to, n,
(GET_LEVEL(from, n, fromtype, 0) + GET_LEVEL(from, n, fromtype, 1)) /2
, totype, 0);
}
return();
}
/*else both mono*/
{
for (ULONG n =0; n < length; n++)
{
SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 0), totype, 0);
}
}
}
void setb_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
{ *((BYTE *) start + pos) = level >>8; }
void setw_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
{ *((WORD *) start + pos) = level; }
void setl_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
{ *((float *) start + pos) = (float)level; }
void setsb_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
{ *((BYTE *) start + (pos <<1) +chan) = level >>8; }
void setsw_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
{ *((WORD *) start + (pos <<1) +chan) = level; }
void setsl_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
{ *((float *) start + (pos <<1) +chan) = (float)level; }
void setnon_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
{}
LONG getb_lev (BYTE *start, ULONG pos, UBYTE dummy)
{ return (*(start + pos) <<8); }
LONG getw_lev (BYTE *start, ULONG pos, UBYTE dummy)
{ return (*((WORD *)start + pos)); }
LONG getl_lev (BYTE *start, ULONG pos, UBYTE dummy)
{ return ((WORD) *((float *)start + pos)); }
LONG getsb_lev (BYTE *start, ULONG pos, UBYTE chan)
{ return (*(start + (pos <<1) +chan) <<8); }
LONG getsw_lev (BYTE *start, ULONG pos, UBYTE chan)
{ return (*((WORD *)start + (pos <<1) +chan)); }
LONG getsl_lev (BYTE *start, ULONG pos, UBYTE chan)
{ return ((WORD) *((float *)start + (pos <<1) +chan)); }
LONG getnon_lev (BYTE *start, ULONG pos, UBYTE dummy)
{ return (0); }
#endif /*NO_DATA_HELP*/