/* $Id: aiff_write.c,v 1.8 2006/09/16 10:07:48 toad32767 Exp $ */ /** ** 2005, 2006 by Marco Trillo ** This file is part of UModPlayer, and is released by ** its autors to the Public Domain. ** In case it's not legally possible, its autors grant ** anyone the right to use, redistribute and modify ** this software for any purpose, without any conditions, ** unless such conditions are required by law. ** ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE ** USE OR MISUSE OF THIS SOFTWARE. **/ /* * =================================================== * Apple/SGI AIFF files * Use LibAiff to write the files * =================================================== */ #include #include #include #include #include #include EXPORT int WriteAIFF(const char *rfile, int bitsPerSample) { AIFF_WriteRef out; IFFType typ; uint8_t buffer[65536]; int32_t *samples = (int32_t *) buffer; int bytes_out; int samples_read; int order; char *name, *annotations; int i, n; /* XXX -- variables used for ugly hack */ char *filenam; int verbosity; if (file.name == NULL) { return (0); } /* * We`ll tell ModPlug to deliver 32-bit audio. * Then LibAiff should do the conversion to 'bitsPerSample' */ CoreSound_BitsPerSample = 32; CoreSound_InitOptions(); /* * XXX -- ugly hack to get rid of LibModPlug 0.8 settings updating annoyance. * XXX LibModPlug will not update 'basic' settings such as * XXX sampling rate or bits-per-sample until a new module is loaded... */ filenam = strcopyof(file.name); if (filenam == NULL) { error("%s", MESSAGE_NO_MEMORY); exit(UM_ERR_MEMORY); } UFreeFile(); verbosity = sets.verbosity; sets.verbosity = 0; /* XXX -- to avoid the call to DrawInfoTable() */ file.name = filenam; file.malloc = TRUE; ULoadFile(); sets.verbosity = verbosity; if (file.name == NULL) { return (0); } CoreSound_BitsPerSample = 32; CoreSound_InitOptions(); /* end of ugly hack */ notice("Exporting audio as AIFF ('%s')\n", rfile); /* Open the output stream */ out = AIFF_WriteOpen(rfile); if (out == NULL) return 0; /* Set the sound options. */ if (AIFF_SetSoundFormat(out, sets.channels, sets.samplerate, bitsPerSample) < 1) { AIFF_WriteClose(out); return 0; } /* Write the song name */ name = (char *) ModPlug_GetName(file.mod); memcpy(&typ, NameID, 4); if (AIFF_SetAttribute(out, typ, name) < 1) { AIFF_WriteClose(out); return 0; } /* Write the module comments (annotations), if any */ annotations = ModPlug_GetMessage(file.mod); if (annotations) { n = strlen(annotations); for (i = 0; i < n; ++i) { if (annotations[i] == '\r') annotations[i] = '\n'; } memcpy(&typ, AnnoID, 4); if (AIFF_SetAttribute(out, typ, annotations) < 1) { AIFF_WriteClose(out); return 0; } } /* Go to 'startpos' */ ModPlug_SeekOrder(file.mod, startpos); /* Now start writing the actual sound */ if (AIFF_StartWritingSamples(out) < 1) { AIFF_WriteClose(out); return 0; } while ((bytes_out = ModPlug_Read(file.mod, buffer, 65536)) > 0) { if (bytes_out & 0x3) { /* if( bytes_out % 4 != 0 ) */ error("read error!\n"); break; } samples_read = bytes_out >> 2; /* bytes_out / 4 */ if (AIFF_WriteSamples32Bit(out, samples, samples_read) < 1) { AIFF_WriteClose(out); return 0; } /* * Check if we have to finish reading */ if (endpos > 0) { order = ModPlug_GetCurrentOrder(file.mod); if (order >= endpos) break; } } AIFF_EndWritingSamples(out); AIFF_WriteClose(out); notice("done\n"); return 1; }