/**************************************************************************/ /* 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 #include #include #include #include #include "dsound.h" 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; /*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) 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; next=left; /*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 data left, do nothing*/ if(dest==NULL || left == NULL) return; /*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*/ FreeMem(temp,temp->blockLength+8); 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) 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; next=right; /*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 data right, do nothing*/ if(dest==NULL || right == NULL) return; /*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*/ FreeMem(temp,temp->blockLength+8); return; }