home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1998 #5
/
AmigaPlus_CD-ROM_Nr.5-98.iso
/
system
/
dsound
/
source.lha
/
Mem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-18
|
6KB
|
248 lines
/**************************************************************************/
/* Mem.c */
/*Contains code for reading an entire sample into memory at once */
/*This is used when it isn't practical to read the sound sample from */
/*disk as it is played (e.g. when the sample is on a floppy). */
/*Data is read in in blocks that are the same size as the buffer size */
/*(optionally) specified by the user using the -b flag, thereby not */
/*requiring the user to have a block of contiguous memory as large as */
/*the sample. */
/*The memory blocks are stored as a linked list; there are two linked */
/*lists, one for each channel of a stereo sample (the list for the left */
/*channel is used if a mono sample is being played) */
/**************************************************************************/
#include <exec/types.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "dsound.h"
extern BOOL loop;
typedef struct memBlock
{
struct memBlock *next; /*The next memory block in the list*/
ULONG blockLength; /*The size of this memory block*/
} memBlock;
/*The linked-list head pointers for each channel*/
memBlock *left=NULL;
memBlock *right=NULL;
memBlock *leftHeader=NULL;
memBlock *rightHeader=NULL;
/*Read the sample (pointed to by file) into memory*/
void storeLeft(BPTR file,ULONG length,ULONG blockLength)
{
memBlock *temp;
memBlock *lastLeft;
/*Loop while there's data to be stored...*/
while(length!=0)
{
/*Get the amount of data to be read next (max of blockLength bytes)*/
blockLength=MIN(blockLength,length);
/*Allocate the memory*/
temp=(memBlock *)AllocMem(blockLength+8,0L);
/*Exit if there was a problem*/
if(temp==NULL)
{
WriteMsg("Couldn't allocate needed memory\n");
cleanup(500);
}
/*Get the length of the data block*/
temp->blockLength=blockLength;
temp->next=NULL;
if(left==NULL)
leftHeader=left=lastLeft=temp; /*First block of data...*/
else
{ /* Add another block to the end of the list*/
lastLeft->next=temp;
lastLeft=temp;
}
/*Actually read the data, now that the allocated memory block*/
/*is in place*/
Read(file,lastLeft+1,blockLength);
/*Subtract the amount read from the total yet to read*/
length-=blockLength;
}
return;
}
/*Delete any remaining memory blocks associated with the left channel*/
void deleteLeft(void)
{
memBlock *temp,*next;
if(leftHeader==NULL)
next=left;
else
next=leftHeader;
/*Loop until we run out of memory blocks*/
while(next!=NULL)
{
/*Get the next block*/
temp=next;
next=temp->next;
/*Free the current block*/
FreeMem(temp,temp->blockLength+8);
}
return;
}
/*Get the next available block of sample data associated with the */
/*left channel*/
void getLeft(APTR dest)
{
memBlock *temp;
/*If there is no dest left, do nothing*/
if(dest==NULL)
return;
/*If there is no data left, try to start over from the beginning*/
if(left==NULL)
{
if(leftHeader==NULL)
return;
left=leftHeader;
}
/*Copy the sample data from the memory block to the destination buffer*/
CopyMem(left+1,dest,left->blockLength);
/*Set the next block as the head of the list*/
temp=left;
left=left->next;
/*Free the memory whose contents we just copied, if we're not looping*/
if(loop==FALSE)
{
FreeMem(temp,temp->blockLength+8);
leftHeader=NULL;
}
return;
}
/*Read the sample (pointed to by file) into memory*/
void storeRight(BPTR file,ULONG length,ULONG blockLength)
{
memBlock *temp;
memBlock *lastRight;
/*Loop while there's data to be stored...*/
while(length!=0)
{
/*Get the amount of data to be read next (max of blockLength bytes)*/
blockLength=MIN(blockLength,length);
/*Allocate the memory*/
temp=(memBlock *)AllocMem(blockLength+8,0L);
/*Exit if there was a problem*/
if(temp==NULL)
{
WriteMsg("Couldn't allocate needed memory\n");
cleanup(500);
}
/*Get the length of the data block*/
temp->blockLength=blockLength;
temp->next=NULL;
if(right==NULL)
rightHeader=right=lastRight=temp; /*First block of data...*/
else
{ /* Add another block to the end of the list*/
lastRight->next=temp;
lastRight=temp;
}
/*Actually read the data, now that the allocated memory block*/
/*is in place*/
Read(file,lastRight+1,blockLength);
/*Subtract the amount read from the total yet to read*/
length-=blockLength;
}
return;
}
/*Delete any remaining memory blocks associated with the right channel*/
void deleteRight(void)
{
memBlock *temp,*next;
if(rightHeader==NULL)
next=right;
else
next=rightHeader;
/*Loop until we run out of memory blocks*/
while(next!=NULL)
{
/*Get the next block*/
temp=next;
next=temp->next;
/*Free the current block*/
FreeMem(temp,temp->blockLength+8);
}
return;
}
/*Get the next available block of sample data associated with the */
/*right channel*/
void getRight(APTR dest)
{
memBlock *temp;
/*If there is no dest, do nothing*/
if(dest==NULL)
return;
/*If there is no data right, try to start over from the beginning*/
if(right==NULL)
{
if(rightHeader==NULL)
return;
right=rightHeader;
}
/*Copy the sample data from the memory block to the destination buffer*/
CopyMem(right+1,dest,right->blockLength);
/*Set the next block as the head of the list*/
temp=right;
right=right->next;
/*Free the memory whose contents we just copied, if we're not looping*/
if(loop==FALSE)
{
FreeMem(temp,temp->blockLength+8);
rightHeader=NULL;
}
return;
}