Index: test/test.c
===================================================================
--- test/test.c	(revision 743)
+++ test/test.c	(working copy)
@@ -28,6 +28,7 @@
           "    -m: print metadata only, don't decode\n"
           "    -x: decode and print adxencd command line to encode as ADX\n"
           "    -g: decode and print oggenc command line to encode as OGG\n"
+          "    -F: decode and print flac command line to encode as FLAC\n"
           "    -b: decode and print batch variable commands\n"
           "    -e: force end-to-end looping\n"
           "    -E: force end-to-end looping even if file has real loop points\n"
@@ -55,12 +56,13 @@
     int metaonly = 0;
     int adxencd = 0;
     int oggenc = 0;
+    int flac = 0;
     int batchvar = 0;
     double loop_count = 2.0;
     double fade_seconds = 10.0;
     double fade_delay_seconds = 0.0;
 
-    while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeEr:gb")) != -1) {
+    while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeEr:gbF")) != -1) {
         switch (opt) {
             case 'o':
                 outfilename = optarg;
@@ -108,6 +110,9 @@
             case 'r':
                 reset_outfilename = optarg;
                 break;
+	    case 'F':
+		flac = 1;
+		break;
             default:
                 usage(argv[0]);
                 return 1;
@@ -209,6 +214,12 @@
             if (s->loop_flag) printf(" -c LOOPSTART=%d -c LOOPLENGTH=%d",s->loop_start_sample,
                     s->loop_end_sample-s->loop_start_sample);
             printf("\n");
+	} else if (flac) {
+	    printf("flac");
+	    if (!metaonly) printf(" \"%s\"",outfilename);
+	    if (s->loop_flag) printf(" -T LOOPSTART=%d -T LOOPLENGTH=%d",s->loop_start_sample,
+		    s->loop_end_sample-s->loop_start_sample);
+	    printf("\n");
         } else if (batchvar) {
             if (!metaonly) printf("set fname=\"%s\"\n",outfilename);
             printf("set tsamp=%d\nset chan=%d\n", s->num_samples, s->channels);
@@ -218,7 +229,7 @@
         else if (metaonly) printf("metadata for %s\n",argv[optind]);
         else printf("decoding %s\n",argv[optind]);
     }
-    if (!play && !adxencd && !oggenc && !batchvar) {
+    if (!play && !adxencd && !oggenc && !batchvar && !flac) {
         char description[1024];
         description[0]='\0';
         describe_vgmstream(s,description,1024);
@@ -232,7 +243,7 @@
     buf = malloc(BUFSIZE*sizeof(sample)*s->channels);
 
     len = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,s);
-    if (!play && !adxencd && !oggenc && !batchvar) printf("samples to play: %d (%.2lf seconds)\n",len,(double)len/s->sample_rate);
+    if (!play && !adxencd && !oggenc && !batchvar && !flac) printf("samples to play: %d (%.2lf seconds)\n",len,(double)len/s->sample_rate);
     fade_samples = fade_seconds * s->sample_rate;
 
     /* slap on a .wav header */
Index: test/Makefile
===================================================================
--- test/Makefile	(revision 743)
+++ test/Makefile	(working copy)
@@ -1,6 +1,6 @@
 export SHELL = /bin/sh
 export CFLAGS=-Wall -ggdb
-export LDFLAGS=-lm -L../src -lvgmstream -lvorbisfile -lmpg123
+export LDFLAGS=-lm -L../src -lvgmstream -lvorbisfile -lmpg123 -lFLAC
 export STRIP=strip
 
 .PHONY: libvgmstream.a
Index: unix/data.c
===================================================================
--- unix/data.c	(revision 743)
+++ unix/data.c	(working copy)
@@ -99,6 +99,7 @@
   "kraw",
 
   "leg",
+  "lflac",
   "logg",
   "lps",
   "lwav",
Index: configure.in
===================================================================
--- configure.in	(revision 743)
+++ configure.in	(working copy)
@@ -27,14 +27,18 @@
         [AC_MSG_ERROR([Cannot find libmpg123])]
 )
 
+PKG_CHECK_MODULES(FLAC, [flac],,
+	[AC_MSG_ERROR([Cannot find libflac])]
+)
+
 dnl Check for GTK/GLib/GThread/Pango
 
 PKG_CHECK_MODULES(GTK, [glib-2.0 >= 2.6.0 gtk+-2.0 >= 2.6.0 gthread-2.0 pango],
     , [AC_MSG_ERROR([Cannot find glib2/gtk2/pango])]
 )
 
-CFLAGS="$CFLAGS $AUDACIOUS_CFLAGS"
-LIBS="$LIBS $AUDACIOUS_LIBS $GTK_LIBS $VORBISFILE_LIBS $MPG123_LIBS"
+CFLAGS="$CFLAGS $AUDACIOUS_CFLAGS $FLAC_CFLAGS"
+LIBS="$LIBS $AUDACIOUS_LIBS $GTK_LIBS $VORBISFILE_LIBS $MPG123_LIBS $FLAC_LIBS"
 
 plugindir=`pkg-config audacious --variable=plugin_dir`
 AC_SUBST(plugindir)
Index: src/coding/coding.h
===================================================================
--- src/coding/coding.h	(revision 743)
+++ src/coding/coding.h	(working copy)
@@ -93,4 +93,8 @@
 
 void decode_SASSC(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
 
+#ifdef VGM_USE_FLAC
+void decode_FLAC(flac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
 #endif
+
+#endif
Index: src/coding/Makefile.unix.am
===================================================================
--- src/coding/Makefile.unix.am	(revision 743)
+++ src/coding/Makefile.unix.am	(working copy)
@@ -26,5 +26,6 @@
 libcoding_la_SOURCES += nds_procyon_decoder.c
 libcoding_la_SOURCES += l5_555_decoder.c
 libcoding_la_SOURCES += SASSC_decoder.c
+libcoding_la_SOURCES += flac_decoder.c
 
 EXTRA_DIST = coding.h g72x_state.h
Index: src/coding/flac_decoder.c
===================================================================
--- src/coding/flac_decoder.c	(revision 0)
+++ src/coding/flac_decoder.c	(revision 0)
@@ -0,0 +1,44 @@
+#include "../vgmstream.h"
+
+#ifdef VGM_USE_FLAC
+#include <FLAC/all.h>
+#include "coding.h"
+#include "../util.h"
+
+void decode_FLAC(flac_codec_data *data, sample *outbuf, int32_t samples_to_do, int channels) {
+    int samples_done = 0;
+
+    do {
+	/* Read a new frame if we need to. */
+	while (data->prev_sample >= data->cur_frame->header.blocksize) {
+	    if (!FLAC__stream_decoder_process_single(data->flac_decoder))
+		return;
+	}
+
+	if (data->cur_frame) {
+	    /* First, how many samples CAN we copy? */
+	    long max_samples =
+		data->cur_frame->header.blocksize - data->prev_sample;
+	    long needed_samples = samples_to_do - samples_done;
+	    long samples_to_copy = needed_samples;
+
+	    if (needed_samples > max_samples) samples_to_copy = max_samples;
+
+	    int i, j;
+	    for (i = 0; i < samples_to_copy; i++) {
+		for (j = 0; j < channels; j++) {
+		    /* This should be outputting little-endian,
+		       sample-size, and signed, but I don't know. */
+		    outbuf[samples_done*channels + j] =
+			data->buffers[j][data->prev_sample + i];
+		}
+		samples_done++;
+	    }
+	    
+	    data->prev_sample += samples_to_copy;
+	}
+	else return;
+    } while (samples_done < samples_to_do);
+}
+
+#endif
Index: src/meta/meta.h
===================================================================
--- src/meta/meta.h	(revision 743)
+++ src/meta/meta.h	(working copy)
@@ -439,4 +439,8 @@
 
 VGMSTREAM * init_vgmstream_dmsg(STREAMFILE* streamFile);
 
+#ifdef VGM_USE_FLAC
+VGMSTREAM * init_vgmstream_flac(STREAMFILE * streamFile);
 #endif
+
+#endif
Index: src/meta/Makefile.unix.am
===================================================================
--- src/meta/Makefile.unix.am	(revision 743)
+++ src/meta/Makefile.unix.am	(working copy)
@@ -178,5 +178,6 @@
 libmeta_la_SOURCES += his.c
 libmeta_la_SOURCES += ps2_ast.c
 libmeta_la_SOURCES += dmsg_segh.c
+libmeta_la_SOURCES += flac_file.c
 
 EXTRA_DIST = meta.h
Index: src/meta/flac_file.c
===================================================================
--- src/meta/flac_file.c	(revision 0)
+++ src/meta/flac_file.c	(revision 0)
@@ -0,0 +1,262 @@
+#include "../vgmstream.h"
+
+#ifdef VGM_USE_FLAC
+
+#include <stdio.h>
+#include <string.h>
+#include "meta.h"
+#include "../util.h"
+#include <FLAC/all.h>
+
+
+static FLAC__StreamDecoderReadStatus read_func(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
+{
+    flac_codec_data *data = client_data;
+
+    size_t bytes_read;
+   
+    bytes_read = read_streamfile(buffer, data->f_streamfile.offset,
+	    *bytes, data->f_streamfile.streamfile);
+
+    data->f_streamfile.offset += bytes_read;
+    *bytes = bytes_read;
+
+    if (bytes_read == 0) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+    else return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+}
+
+static FLAC__StreamDecoderSeekStatus seek_func(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) {
+    flac_codec_data *data = client_data;
+
+    if (absolute_byte_offset > data->f_streamfile.size) {
+        return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+    } else {
+        data->f_streamfile.offset = absolute_byte_offset;
+        return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+    }
+}
+
+static FLAC__StreamDecoderTellStatus tell_func(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) {
+    flac_codec_data *data = client_data;
+    *absolute_byte_offset = data->f_streamfile.offset;
+    return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+}
+
+static FLAC__StreamDecoderLengthStatus length_func(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) {
+    flac_codec_data *data = client_data;
+    *stream_length = data->f_streamfile.size;
+    return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+}
+
+static FLAC__bool eof_func(const FLAC__StreamDecoder *decoder, void *client_data) {
+    flac_codec_data *data = client_data;
+    return data->f_streamfile.offset == data->f_streamfile.size;
+}
+
+static FLAC__StreamDecoderWriteStatus write_func(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) {
+    flac_codec_data *data = client_data;
+    int i;
+    
+    /* Clean up from last write. */
+    if (data->buffers) {
+	for (i = 0; i < data->cur_frame->header.channels; i++) free(data->buffers[i]);
+	free(data->buffers);
+    }
+    if (data->cur_frame) free(data->cur_frame);
+    data->buffers = NULL;
+    data->cur_frame = NULL;
+    
+    /* Copy the data into the codec data so we can get access to it
+       elsewhere. */
+    data->cur_frame = calloc(1,sizeof(FLAC__Frame));
+    if (!data->cur_frame) goto fail;
+    memcpy(data->cur_frame, frame, sizeof(FLAC__Frame));
+    
+    data->buffers = calloc(1,data->cur_frame->header.channels*sizeof(FLAC__int32 *));
+    if (!data->buffers) goto fail;
+    for (i = 0; i < data->cur_frame->header.channels; i++) {
+	data->buffers[i] = calloc(1,data->cur_frame->header.blocksize*sizeof(FLAC__int32));
+	if (!data->buffers[i]) goto fail;
+	memcpy(data->buffers[i], buffer[i], data->cur_frame->header.blocksize*sizeof(FLAC__int32));
+    }
+    data->prev_sample = 0;
+
+    return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+
+    /* clean up anything we may have opened */
+fail:
+    if (data->buffers) {
+	for (i = 0; i < data->cur_frame->header.channels; i++) free(data->buffers[i]);
+	free(data->buffers);
+    }
+    if (data->cur_frame) free(data->cur_frame);
+    data->buffers = NULL;
+    data->cur_frame = NULL;
+    
+    return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+}
+
+static void metadata_func(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) {
+    flac_codec_data *data = client_data;
+    int i;
+    
+    if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
+	/* Read for LOOPSTART/LOOPLENGTH fields. */
+	for (i = 0; i < metadata->data.vorbis_comment.num_comments; i++) {
+	    FLAC__StreamMetadata_VorbisComment_Entry entry =
+		metadata->data.vorbis_comment.comments[i];
+	    
+            if (strstr((char *)entry.entry,"LOOPSTART=")==(char*)entry.entry) {
+                data->loop_start=atol(strrchr((char *)entry.entry,'=')+1);
+                if (data->loop_start >= 0)
+                    data->loop_flag=1;
+	    }
+            else if (strstr((char *)entry.entry,"LOOPLENGTH=")==(char*)entry.entry) {
+                data->loop_length=atol(strrchr((char *)entry.entry,'=')+1);
+                data->loop_length_found=1;
+            }
+	}
+    }
+}
+
+static void err_func(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) {
+    flac_codec_data *data = client_data;
+    
+    data->has_error = 1;
+    data->error = status;
+}
+
+/* FLAC, by way of libflac */
+
+/* Basically, we sorta copy the vorbis way of doing things, and
+   proceed by using FLAC__stream_decoder_init_stream given that we've
+   already got a STREAMFILE struct to handle access. */
+
+VGMSTREAM * init_vgmstream_flac(STREAMFILE *streamFile) {
+    VGMSTREAM * vgmstream = NULL;
+    char filename[260];
+
+    FLAC__StreamDecoder *decoder;
+    flac_codec_data *data;
+
+    int ogg_flac = 0;
+
+    /* check extension, case insensitive */
+    streamFile->get_name(streamFile,filename,sizeof(filename));
+    
+    /* It is only interesting to use flacs with vgmstream if they are
+       looped.  To prevent such files from being played by other
+       plugins and such they may be renamed to .lflac. This meta
+       reader should still support .flac, though. We also support Ogg
+       FLAC, so we check for .logg and .ogg as well. The difference in
+       the streams should let this module pick it up where the vorbis
+       one failed. */
+    if (strcasecmp("lflac",filename_extension(filename)) &&
+            strcasecmp("flac",filename_extension(filename)) &&
+	    strcasecmp("logg",filename_extension(filename)) &&
+	    strcasecmp("ogg",filename_extension(filename))
+       ) {
+        goto fail;
+    }
+
+    /* proceed to open a STREAMFILE just for this stream */
+    data = calloc(1,sizeof(flac_codec_data));
+    if (!data) goto fail;
+
+    data->f_streamfile.streamfile = streamFile->open(streamFile,filename,
+            STREAMFILE_DEFAULT_BUFFER_SIZE);
+    if (!data->f_streamfile.streamfile) goto fail;
+    data->f_streamfile.offset = 0;
+    data->f_streamfile.size = get_streamfile_size(data->f_streamfile.streamfile);
+
+    /* There are two options...  We might be passed a FLAC file or an
+       Ogg FLAC file.  So we need to be able to do both. */
+    decoder = FLAC__stream_decoder_new();
+    if (!decoder) goto fail;
+    /* We want to get all comments. */
+    FLAC__stream_decoder_set_metadata_respond(decoder,
+        FLAC__METADATA_TYPE_VORBIS_COMMENT);
+    /* Now we can open the file. */
+    if (FLAC__stream_decoder_init_stream(decoder, read_func, seek_func,
+	    tell_func, length_func, eof_func, write_func, metadata_func,
+	    err_func, data)
+	        != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
+#ifdef FLAC_API_SUPPORTS_OGG_FLAC
+	/* Try Ogg FLAC before failing */
+	if (FLAC__stream_decoder_init_ogg_stream(decoder, read_func, seek_func,
+	        tell_func, length_func, eof_func, write_func, metadata_func,
+		err_func, data)
+	            != FLAC__STREAM_DECODER_INIT_STATUS_OK) goto fail;
+	else ogg_flac = 1;
+#else
+	goto fail;
+#endif
+    }
+    data->flac_decoder = decoder;
+
+    /* grab the comments */
+    if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
+        goto fail; /* There was a failure reading the metadata. */
+    
+    /* Since FLAC works using callbacks, our data struct should now be
+       populated with any interesting comments. */
+    
+    /* Gotta parse one audio frame before this will work. */
+    FLAC__stream_decoder_process_single(decoder);
+    
+    /* build the VGMSTREAM */
+    vgmstream = allocate_vgmstream(FLAC__stream_decoder_get_channels(decoder),
+        data->loop_flag);
+    if (!vgmstream) goto fail;
+
+    /* store our fun extra datas */
+    vgmstream->codec_data = data;
+
+    /* fill in the vital statistics */
+    vgmstream->channels = FLAC__stream_decoder_get_channels(decoder);
+    vgmstream->sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
+
+    /* let's play the whole file */
+    vgmstream->num_samples = FLAC__stream_decoder_get_total_samples(decoder);
+
+    if (data->loop_flag) {
+        vgmstream->loop_start_sample = data->loop_start;
+        if (data->loop_length_found)
+            vgmstream->loop_end_sample = data->loop_start+data->loop_length;
+        else if (data->loop_end_found)
+            vgmstream->loop_end_sample = data->loop_end;
+        else
+            vgmstream->loop_end_sample = vgmstream->num_samples;
+        vgmstream->loop_flag = data->loop_flag;
+
+        if (vgmstream->loop_end_sample > vgmstream->num_samples)
+            vgmstream->loop_end_sample = vgmstream->num_samples;
+    }
+    vgmstream->coding_type = coding_FLAC;
+    if (ogg_flac)
+        vgmstream->layout_type = layout_ogg_flac;
+    else
+	vgmstream->layout_type = layout_flac;
+    vgmstream->meta_type = meta_FLAC;
+
+    return vgmstream;
+
+    /* clean up anything we may have opened */
+fail:
+    printf("failed!\n");
+    if (data) {
+        if (data->flac_decoder)
+            FLAC__stream_decoder_finish(data->flac_decoder);
+        if (data->f_streamfile.streamfile)
+            close_streamfile(data->f_streamfile.streamfile);
+        free(data);
+    }
+    if (decoder) FLAC__stream_decoder_delete(decoder);
+    if (vgmstream) {
+        vgmstream->codec_data = NULL;
+        close_vgmstream(vgmstream);
+    }
+    return NULL;
+}
+
+#endif
Index: src/vgmstream.c
===================================================================
--- src/vgmstream.c	(revision 743)
+++ src/vgmstream.c	(working copy)
@@ -240,6 +240,9 @@
     init_vgmstream_his,
 	init_vgmstream_ps2_ast,
 	init_vgmstream_dmsg,
+#ifdef VGM_USE_FLAC
+    init_vgmstream_flac,
+#endif
 };
 
 #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
@@ -385,6 +388,14 @@
         nwa_codec_data *data = vgmstream->codec_data;
         reset_nwa(data->nwa);
     }
+
+#ifdef VGM_USE_FLAC
+    if (vgmstream->layout_type==layout_flac) {
+	flac_codec_data *data = vgmstream->codec_data;
+	
+	FLAC__stream_decoder_reset(data->flac_decoder);
+    }
+#endif
 }
 
 /* simply allocate memory for the VGMSTREAM and its channels */
@@ -572,6 +583,29 @@
         vgmstream->codec_data = NULL;
     }
 
+#ifdef VGM_USE_FLAC
+    if (vgmstream->coding_type==coding_FLAC) {
+        flac_codec_data *data = vgmstream->codec_data;
+        if (vgmstream->codec_data) {
+            FLAC__StreamDecoder *decoder = data->flac_decoder;
+	    int i;
+
+	    FLAC__stream_decoder_finish(decoder);
+	    FLAC__stream_decoder_delete(decoder);
+
+	    if (data->buffers) {
+		for (i = 0; i < data->cur_frame->header.channels; i++) free(data->buffers[i]);
+		free(data->buffers);
+	    }
+	    if (data->cur_frame) free(data->cur_frame);
+
+            close_streamfile(data->f_streamfile.streamfile);
+            free(vgmstream->codec_data);
+            vgmstream->codec_data = NULL;
+        }
+    }
+#endif
+
     /* now that the special cases have had their chance, clean up the standard items */
     for (i=0;i<vgmstream->channels;i++) {
         if (vgmstream->ch[i].streamfile) {
@@ -618,6 +652,10 @@
         case layout_mpeg:
 #endif
         case layout_dtk_interleave:
+#ifdef VGM_USE_FLAC
+        case layout_flac:
+        case layout_ogg_flac:
+#endif
         case layout_none:
             render_vgmstream_nolayout(buffer,sample_count,vgmstream);
             break;
@@ -700,6 +738,9 @@
         case coding_NWA4:
         case coding_NWA5:
         case coding_SASSC:
+#ifdef VGM_USE_FLAC
+        case coding_FLAC:
+#endif
             return 1;
         case coding_NDS_IMA:
         case coding_DAT4_IMA:
@@ -1200,6 +1241,13 @@
             }
 
             break;
+#ifdef VGM_USE_FLAC
+        case coding_FLAC: /* Test this. */
+            decode_FLAC(vgmstream->codec_data,
+                    buffer+samples_written*vgmstream->channels,samples_to_do,
+                    vgmstream->channels);
+            break;
+#endif
     }
 }
 
@@ -1303,6 +1351,15 @@
                 seek_nwa(data->nwa, vgmstream->loop_sample);
             }
 
+#ifdef VGM_USE_FLAC
+            if (vgmstream->coding_type==coding_FLAC) {
+                flac_codec_data *data =
+                    (flac_codec_data *)(vgmstream->codec_data);
+                FLAC__StreamDecoder *decoder = data->flac_decoder;
+                
+                FLAC__stream_decoder_seek_absolute(decoder, vgmstream->loop_sample);
+            }
+#endif
             /* restore! */
             memcpy(vgmstream->ch,vgmstream->loop_ch,sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
             vgmstream->current_sample=vgmstream->loop_sample;
@@ -1550,6 +1607,11 @@
         case coding_SASSC:
             snprintf(temp,TEMPSIZE,"Activision / EXAKT SASSC 8-bit DPCM");
             break;
+#ifdef VGM_USE_FLAC
+        case coding_FLAC:
+            snprintf(temp,TEMPSIZE,"FLAC");
+            break;
+#endif
         default:
             snprintf(temp,TEMPSIZE,"CANNOT DECODE");
     }
@@ -1659,6 +1721,14 @@
         case layout_ivaud_blocked:
             snprintf(temp,TEMPSIZE,"GTA IV blocked");
             break;
+#ifdef VGM_USE_FLAC
+        case layout_flac:
+            snprintf(temp,TEMPSIZE,"FLAC stream");
+            break;
+        case layout_ogg_flac:
+	    snprintf(temp,TEMPSIZE,"Ogg");
+	    break;
+#endif
         default:
             snprintf(temp,TEMPSIZE,"INCONCEIVABLE");
     }
@@ -2387,6 +2457,11 @@
 		case meta_DMSG:
             snprintf(temp,TEMPSIZE,"RIFF/DMSGsegh header");
             break;
+#ifdef VGM_USE_FLAC
+        case meta_FLAC:
+            snprintf(temp,TEMPSIZE,"FLAC");
+            break;
+#endif
         default:
            snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
     }
Index: src/vgmstream.h
===================================================================
--- src/vgmstream.h	(revision 743)
+++ src/vgmstream.h	(working copy)
@@ -5,12 +5,13 @@
 #ifndef _VGMSTREAM_H
 #define _VGMSTREAM_H
 
-/* Vorbis and MPEG decoding are done by external libraries.
+/* Vorbis, FLAC, and MPEG decoding are done by external libraries.
  * If someone wants to do a standalone build, they can do it by simply
  * removing these defines (and the references to the libraries in the
  * Makefile) */
 #define VGM_USE_VORBIS
 #define VGM_USE_MPEG
+#define VGM_USE_FLAC
 
 #include "streamfile.h"
 #include "coding/g72x_state.h"
@@ -22,6 +23,9 @@
 #endif
 #include "coding/acm_decoder.h"
 #include "coding/nwa_decoder.h"
+#ifdef VGM_USE_FLAC
+#include <FLAC/all.h>
+#endif
 
 /* The encoding type specifies the format the sound data itself takes */
 typedef enum {
@@ -105,6 +109,10 @@
     coding_AICA,            /* Yamaha AICA ADPCM */
     coding_L5_555,          /* Level-5 0x555 */
     coding_SASSC,           /* Activision EXAKT SASSC DPCM */
+
+#ifdef VGM_USE_FLAC
+    coding_FLAC,            /* FLAC */
+#endif
 } coding_t;
 
 /* The layout type specifies how the sound data is laid out in the file */
@@ -155,6 +163,10 @@
     layout_aix,             /* CRI AIX's wheels within wheels */
     layout_aax,             /* CRI AAX's wheels within databases */
 	layout_ivaud_blocked,	/* GTA IV .ivaud blocks */
+#ifdef VGM_USE_FLAC
+    layout_flac,            /* native FLAC file (not Ogg FLAC) */
+    layout_ogg_flac,        /* Ogg FLAC */
+#endif
 } layout_t;
 
 /* The meta type specifies how we know what we know about the file. We may know because of a header we read, some of it may have been guessed from filenames, etc. */
@@ -428,6 +440,9 @@
     meta_XBOX_HLWAV,        /* Half Life 2 (XBOX) */
 	meta_PS2_AST,			/* Some KOEI game (PS2) */
 	meta_DMSG,				/* Nightcaster II - Equinox (XBOX) */
+#ifdef VGM_USE_FLAC
+    meta_FLAC,              /* Standalone FLAC (not ogg-FLAC) */
+#endif
 } meta_t;
 
 typedef struct {
@@ -619,6 +634,33 @@
     NWAData *nwa;
 } nwa_codec_data;
 
+#ifdef VGM_USE_FLAC
+typedef struct {
+    STREAMFILE *streamfile;
+    FLAC__uint64 offset;
+    FLAC__uint64 size;
+} flac_streamfile;
+
+typedef struct {
+    FLAC__StreamDecoder *flac_decoder;
+
+    int loop_flag;
+    int32_t loop_start;
+    int32_t loop_length;
+    int loop_length_found;
+    int32_t loop_end;
+    int loop_end_found;
+    
+    flac_streamfile f_streamfile;
+    FLAC__Frame *cur_frame;
+    FLAC__int32 **buffers;
+    int32_t prev_sample;
+    
+    int has_error;
+    FLAC__StreamDecoderErrorStatus error;
+} flac_codec_data;
+#endif
+
 /* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
 VGMSTREAM * init_vgmstream(const char * const filename);
 
Index: src/Makefile
===================================================================
--- src/Makefile	(revision 743)
+++ src/Makefile	(working copy)
@@ -18,7 +18,8 @@
     coding/aica_decoder.o \
     coding/nds_procyon_decoder.o \
     coding/l5_555_decoder.o \
-    coding/SASSC_decoder.o
+    coding/SASSC_decoder.o \
+    coding/flac_decoder.o
 
 LAYOUT_OBJS=layout/ast_blocked.o \
     layout/blocked.o \
@@ -220,7 +221,8 @@
     meta/myspd.o \
     meta/his.o \
     meta/ps2_ast.o \
-    meta/dmsg_segh.o
+    meta/dmsg_segh.o \
+    meta/flac_file.o
     
 OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
 
Index: winamp/in_vgmstream.c
===================================================================
--- winamp/in_vgmstream.c	(revision 743)
+++ winamp/in_vgmstream.c	(working copy)
@@ -165,6 +165,7 @@
     "kraw\0KRAW Audio File (*.KRAW)\0",
 
     "leg\0LEG Audio File (*.LEG)\0",	
+    "lflac\0LFLAC Audio File (*.LFLAC)\0",
     "logg\0LOGG Audio File (*.LOGG)\0",
     "lps\0LPS Audio File (*.LPS)\0",
     "lwav\0LWAV Audio File (*.LWAV)\0",
