215 lines
4.2 KiB
Diff
Executable File
215 lines
4.2 KiB
Diff
Executable File
diff --git a/libaiff.c b/libaiff.c
|
|
index d0ad40d..e266802 100644
|
|
--- a/libaiff.c
|
|
+++ b/libaiff.c
|
|
@@ -44,6 +44,8 @@ static struct decoder* decoders[] = {
|
|
|
|
static AIFF_Ref AIFF_ReadOpen (const char *, int);
|
|
static AIFF_Ref AIFF_WriteOpen (const char *, int);
|
|
+static AIFF_Ref AIFF_ReadOpenW (const wchar_t*, int);
|
|
+static AIFF_Ref AIFF_WriteOpenW (const wchar_t*, int);
|
|
static void AIFF_ReadClose (AIFF_Ref);
|
|
static int AIFF_WriteClose (AIFF_Ref);
|
|
static void* InitBuffer (AIFF_Ref, size_t);
|
|
@@ -53,6 +55,21 @@ static int Prepare (AIFF_Ref);
|
|
static void Unprepare (AIFF_Ref);
|
|
static struct decoder* FindDecoder (IFFType);
|
|
|
|
+#ifdef _WIN32
|
|
+AIFF_Ref
|
|
+AIFF_OpenFileW(const wchar_t *file, int flags)
|
|
+{
|
|
+ AIFF_Ref ref = NULL;
|
|
+
|
|
+ if (flags & F_RDONLY) {
|
|
+ ref = AIFF_ReadOpenW(file, flags);
|
|
+ } else if (flags & F_WRONLY) {
|
|
+ ref = AIFF_WriteOpenW(file, flags);
|
|
+ }
|
|
+
|
|
+ return ref;
|
|
+}
|
|
+#endif
|
|
AIFF_Ref
|
|
AIFF_OpenFile(const char *file, int flags)
|
|
{
|
|
@@ -86,6 +103,76 @@ AIFF_CloseFile(AIFF_Ref ref)
|
|
return r;
|
|
}
|
|
|
|
+#ifdef _WIN32
|
|
+static AIFF_Ref
|
|
+AIFF_ReadOpenW(const wchar_t *file, int flags)
|
|
+{
|
|
+ AIFF_Ref r;
|
|
+ IFFHeader hdr;
|
|
+
|
|
+ r = malloc(kAIFFRefSize);
|
|
+ if (!r) {
|
|
+ return NULL;
|
|
+ }
|
|
+ r->fd = _wfopen(file, L"rb");
|
|
+ if (r->fd == NULL) {
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+ r->flags = F_RDONLY | flags;
|
|
+ if (fread(&hdr, 1, 4, r->fd) < 4) {
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+ switch (hdr.hid) {
|
|
+ case AIFF_TYPE_IFF:
|
|
+ /* Continue reading the IFF header */
|
|
+ if (fread(&(hdr.len), 1, 8, r->fd) < 8) {
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+ if (hdr.len == 0) {
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+ /*
|
|
+ * Check the format type (AIFF or AIFC)
|
|
+ */
|
|
+ r->format = hdr.fid;
|
|
+ switch (r->format) {
|
|
+ case AIFF_TYPE_AIFF:
|
|
+ case AIFF_TYPE_AIFC:
|
|
+ break;
|
|
+ default:
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (init_aifx(r) < 1) {
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ fclose(r->fd);
|
|
+ free(r);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ r->stat = 0;
|
|
+ r->buffer = NULL;
|
|
+ r->buflen = 0;
|
|
+
|
|
+ return r;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
static AIFF_Ref
|
|
AIFF_ReadOpen(const char *file, int flags)
|
|
{
|
|
@@ -450,6 +537,89 @@ AIFF_ReadClose(AIFF_Ref r)
|
|
return;
|
|
}
|
|
|
|
+#ifdef WIN32
|
|
+static AIFF_Ref
|
|
+AIFF_WriteOpenW(const wchar_t *file, int flags)
|
|
+{
|
|
+ AIFF_Ref w;
|
|
+ IFFHeader hdr;
|
|
+ ASSERT(sizeof(IFFHeader) == 12);
|
|
+
|
|
+ w = malloc(kAIFFRefSize);
|
|
+ if (!w) {
|
|
+err0:
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Simultaneous open for reading & writing
|
|
+ */
|
|
+ w->fd = _wfopen(file, L"w+b");
|
|
+ if (w->fd == NULL) {
|
|
+err1:
|
|
+ free(w);
|
|
+ goto err0;
|
|
+ }
|
|
+ hdr.hid = ARRANGE_BE32(AIFF_FORM);
|
|
+ w->len = 4;
|
|
+ hdr.len = ARRANGE_BE32(4);
|
|
+ if (flags & F_AIFC)
|
|
+ hdr.fid = ARRANGE_BE32(AIFF_AIFC);
|
|
+ else
|
|
+ hdr.fid = ARRANGE_BE32(AIFF_AIFF);
|
|
+
|
|
+ if (fwrite(&hdr, 1, 12, w->fd) < 12) {
|
|
+err2:
|
|
+ fclose(w->fd);
|
|
+ goto err1;
|
|
+ }
|
|
+ w->stat = 0;
|
|
+ w->segmentSize = 0;
|
|
+ w->buffer = NULL;
|
|
+ w->buflen = 0;
|
|
+ w->tics = 0;
|
|
+
|
|
+ /*
|
|
+ * If writing AIFF-C, write the required FVER chunk
|
|
+ */
|
|
+ if (flags & F_AIFC) {
|
|
+ IFFChunk chk;
|
|
+ uint32_t vers;
|
|
+ ASSERT(sizeof(IFFChunk) == 8);
|
|
+
|
|
+ chk.id = ARRANGE_BE32(AIFF_FVER);
|
|
+ chk.len = ARRANGE_BE32(4);
|
|
+ vers = ARRANGE_BE32(AIFC_STD_DRAFT_082691);
|
|
+
|
|
+ if (fwrite(&chk, 1, 8, w->fd) < 8 ||
|
|
+ fwrite(&vers, 1, 4, w->fd) < 4) {
|
|
+ goto err2;
|
|
+ }
|
|
+
|
|
+ w->len += 12;
|
|
+
|
|
+ /*
|
|
+ * If no endianness specified for AIFF-C,
|
|
+ * default to big endian
|
|
+ */
|
|
+ if (!(flags & (LPCM_LTE_ENDIAN | LPCM_BIG_ENDIAN))) {
|
|
+ flags |= LPCM_BIG_ENDIAN;
|
|
+ }
|
|
+ } else {
|
|
+ /*
|
|
+ * If writing regular AIFF, make sure we
|
|
+ * write big-endian data
|
|
+ */
|
|
+ flags &= ~LPCM_LTE_ENDIAN;
|
|
+ flags |= LPCM_BIG_ENDIAN;
|
|
+ }
|
|
+
|
|
+ w->flags = F_WRONLY | flags;
|
|
+
|
|
+ return w;
|
|
+}
|
|
+#endif
|
|
+
|
|
static AIFF_Ref
|
|
AIFF_WriteOpen(const char *file, int flags)
|
|
{
|
|
diff --git a/libaiff/libaiff.h b/libaiff/libaiff.h
|
|
index 56fc77f..e1940a5 100644
|
|
--- a/libaiff/libaiff.h
|
|
+++ b/libaiff/libaiff.h
|
|
@@ -165,6 +165,7 @@ typedef struct s_Instrument Instrument ;
|
|
|
|
/* == Function prototypes == */
|
|
AIFF_Ref AIFF_OpenFile(const char *, int) ;
|
|
+AIFF_Ref AIFF_OpenFileW(const wchar_t *, int) ;
|
|
int AIFF_CloseFile(AIFF_Ref) ;
|
|
char* AIFF_GetAttribute(AIFF_Ref,IFFType) ;
|
|
int AIFF_GetInstrumentData(AIFF_Ref,Instrument*) ;
|