/* $Id: pcm_write.c,v 1.5 2006/09/16 10:02:29 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. **/ /* * ========================== * PCM FILE / AUDIO WRITER * ========================== */ #include #include EXPORT unsigned long WritePCM(char *rfile, int format) { int order; int16_t samples[5000]; char *buffer = (char *) samples; int e, d; int fd; int bytes_out, epos, upos, bytes_in; unsigned long length = 0; char *endian; fd = open(rfile, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (fd == -1) { return 0; } ModPlug_SeekOrder(file.mod, startpos); /* Use 16-bit samples */ CoreSound_BitsPerSample = 16; CoreSound_InitOptions(); if (format & EXPORT_BIG_ENDIAN) { endian = "big-endian"; } else if (format & EXPORT_LTE_ENDIAN) { endian = "little-endian"; } else { if (sets.endianness == BIG_ENDIAN) { endian = "big-endian"; } else { endian = "little-endian"; } } notice("Exporting audio to raw 16-bit PCM, %s, sampling rate: %.3f kHz\n", endian, ((double) sets.samplerate) / 1000.0); while ((bytes_out = ModPlug_Read(file.mod, buffer, 10000)) > 0) { length += bytes_out; /* Calculate the number of short values entered in buffer */ d = bytes_out >> 1; /* bytes_out / 2 */ /* * Byteswap if required */ if ((sets.endianness == BIG_ENDIAN && (format & EXPORT_LTE_ENDIAN)) || (sets.endianness == LTE_ENDIAN && (format & EXPORT_BIG_ENDIAN))) { for (e = 0; e < d; ++e) { samples[e] = swap16(samples[e]); } } /* * Write the data to the file. * If the system cant write the 10000-bytes buffer all in one, * we use many write() calls. * * This can be useful for pipes (since raw PCM audio can * be piped in example to a player program). */ upos = 0; bytes_in = bytes_out; for (;;) { epos = write(fd, buffer + upos, bytes_in); if (epos < 1) { close(fd); return 0; } if (epos == bytes_in) break; upos += epos; bytes_in -= epos; } /* * Check if we have to finish reading */ if (endpos > 0) { order = ModPlug_GetCurrentOrder(file.mod); if (order >= endpos) break; } } close(fd); notice("done!\n"); return length; }