/*
**      $VER: SP_WriteSubs.c 3.3 (4.1.97)
**
**      SPObject write API
**
**      (C) Copyright 1994-97 Andreas R. Kleinert
**      All Rights Reserved.
*/

#include "spobject.h"


 /* PUBLIC functions */

ULONG __saveds __asm SPO_Write( register __a1 struct SPObjectHandle *SPObjectHandle_a1,
                                register __a2 struct SPObjectBase   *SPO_SourceBase,
                                register __a3 struct SPObjectHandle *source_handle);


ULONG __saveds __stdargs SPLI_SaveSample(struct SPObjectHandle *SPObjectHandle,
                                         UBYTE *destname,
                                         UBYTE *buffer, ULONG buffersize,
                                         ULONG samplespersec, ULONG volume,
                                         ULONG samplebits);

/* *************************************************** */
/* *                                                 * */
/* * SPO_Write : ...                                 * */
/* *                                                 * */
/* *************************************************** */

/* Use these because of unwished interferences because of same-named
   functions inside this library */
ULONG SPO2_GetSampleBuffer(  APTR handle, UBYTE **buffer, ULONG *buffersize);
ULONG SPO2_GetSampleInfo(    APTR handle, ULONG *samplesPerSec, ULONG *volume, APTR future);
ULONG SPO2_GetSampleList(    APTR handle, struct SPO_SampleList **samplelist);


#pragma libcall SPObjectBase2 SPO2_GetSampleBuffer  84 ba903
#pragma libcall SPObjectBase2 SPO2_GetSampleInfo    8a 1ba904
#pragma libcall SPObjectBase2 SPO2_GetSampleList    90 a902


ULONG __saveds __asm SPO_Write( register __a1 struct SPObjectHandle *SPObjectHandle_a1,
                                register __a2 struct SPObjectBase   *SPO_SourceBase,
                                register __a3 struct SPObjectHandle *source_handle)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
 ULONG retval = SPERR_NO_ERROR;

 struct SPObjectBase    *SPObjectBase2 = SPO_SourceBase;
 struct SPO_SampleList  *SampleList = N;
 struct SPO_SampleEntry *entry;
 ULONG                   count = N;
 char                filename [256];
 UBYTE                   name [256];


 if(!SPObjectHandle) return(SPERR_NO_HANDLE);
 if(SPObjectHandle->ah_Medium != SPO_MEDIUM_DISK) return(SPERR_ACTION_NOT_SUPPORTED);


 if(!XpkBase) XpkBase = (APTR) OpenLibrary("xpkmaster", 2);
 if(!XpkBase) return(SPERR_VERSION_CONFLICT);


 if(strlen(SPObjectHandle->ah_WriteName) > 4)
  {
   if(!stricmp(&SPObjectHandle->ah_WriteName[strlen(SPObjectHandle->ah_WriteName)-4], ".spo"))
    {
          strcpy(filename,     SPObjectHandle->ah_WriteName);
          filename[strlen(filename)-4] = (char) 0;
    }else strcpy(filename,     SPObjectHandle->ah_WriteName);
  }else   strcpy(filename,     SPObjectHandle->ah_WriteName);

 if(!SPObjectHandle->ah_SaveSampleList)
  {
   if(!SPO_SourceBase) return(SPERR_ILLEGAL_ACCESS);
   if(!source_handle)  return(SPERR_NO_HANDLE);

   if(LibVer(SPO_SourceBase) < 2)
    {
     UBYTE *buffer;
     ULONG  buffersize, spsec, volume;

                 retval = SPO2_GetSampleBuffer(source_handle, &buffer, &buffersize);
     if(!retval) retval = SPO2_GetSampleInfo(source_handle, &spsec, &volume, N);
     if(!retval) retval = SPLI_SaveSample(SPObjectHandle,
                                          filename,
                                          buffer,
                                          buffersize,
                                          spsec,
                                          volume,
                                          8);

     return(retval);

   } /* ELSE : */

   retval = SPO2_GetSampleList(source_handle, &SampleList);
   if(retval) return(retval);

  }else SampleList = SPObjectHandle->ah_SaveSampleList;

 if(!SampleList) return(SPERR_ILLEGAL_ACCESS);

 SPObjectHandle->ah_SPOHeader = (struct SPOHeader *) AllocVec(sizeof(struct SPOHeader), (MEMF_CLEAR|MEMF_PUBLIC));
 if(!SPObjectHandle->ah_SPOHeader) return(SPERR_NO_MEMORY);

 for(entry=(APTR) SampleList->sl_EntryList.lh_Head;(entry)&&(entry!=(APTR) &(SampleList->sl_EntryList.lh_Tail));)
  {
   if(entry->se_Type == SE_TYPE_SAMPLE)
    {
     SPO_FreeResources(SPObjectHandle);

     strcpy(name, filename);

     if(count++ > 0) sprintf(&name[strlen(name)], "_%ld", count);

     retval = SPLI_SaveSample(SPObjectHandle,
                              name,
                              entry->se_SampleBuffer,
                              entry->se_SampleSize,
                              entry->se_SamplesPerSec,
                              entry->se_Volume,
                              entry->se_SampleBits);

     if(retval) break;
    }

   entry = (APTR) entry->se_Node.ln_Succ;
  }

 return(retval);
}

ULONG __saveds __stdargs SPLI_SaveSample(struct SPObjectHandle *SPObjectHandle,
                                         UBYTE *destname,
                                         UBYTE *buffer, ULONG buffersize,
                                         ULONG samplespersec, ULONG volume,
                                         ULONG samplebits)
{
 ULONG retval = SPERR_NO_ERROR;
 char destname_spo [256];

 strcpy(destname_spo, destname);
 strcat(destname_spo, ".spo");

 SPObjectHandle->ah_filehandle_dest = Open(destname_spo, MODE_NEWFILE);
 if(!SPObjectHandle->ah_filehandle_dest) return(SPERR_NO_FILE);

 SPObjectHandle->ah_filehandle_dest2 = Open(destname, MODE_NEWFILE);
 if(!SPObjectHandle->ah_filehandle_dest2) return(SPERR_NO_FILE);

 strcpy(SPObjectHandle->ah_SPOHeader->spo_ID, SPO_ID);

 SPObjectHandle->ah_SPOHeader->spo_SampleBits = (UBYTE) samplebits;
 SPObjectHandle->ah_SPOHeader->spo_StereoFlag = (UBYTE) FALSE;

 SPObjectHandle->ah_SPOHeader->spo_Channels   = (UBYTE) 15;
 SPObjectHandle->ah_SPOHeader->spo_Frequency  = (ULONG) samplespersec;
 SPObjectHandle->ah_SPOHeader->spo_Volume     = (ULONG) volume;

 SPObjectHandle->ah_SPOHeader->spo_SampleLength = buffersize;

 Write(SPObjectHandle->ah_filehandle_dest,  SPObjectHandle->ah_SPOHeader, SPOHEADER_SIZE);
 Write(SPObjectHandle->ah_filehandle_dest2,                       buffer,     buffersize);

 return(retval);
}
