diff --git a/FFmpegSource2/ffaudiosource.cpp b/FFmpegSource2/ffaudiosource.cpp
index 6a86deb14dabe9b0d99209a033281098fe1f99cb..a586e74b630707e287bce50b5473e2d48bb2bc8d 100644
--- a/FFmpegSource2/ffaudiosource.cpp
+++ b/FFmpegSource2/ffaudiosource.cpp
@@ -41,6 +41,208 @@ size_t AudioBase::FindClosestAudioKeyFrame(int64_t Sample) {
 	return Frames.size() - 1;
 }
 
+int FFAudioSource::GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize) {
+	if (Index < 0) {
+		Index = -1;
+		for (unsigned int i = 0; i < FormatContext->nb_streams; i++)
+			if (FormatContext->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
+				Index = i;
+				break;
+			}
+	}
+
+	if (Index < 0) {
+		_snprintf(ErrorMsg, MsgSize, "No audio track found");
+		return 1;
+	}
+
+	if (Index >= (int)FormatContext->nb_streams) {
+		_snprintf(ErrorMsg, MsgSize, "Invalid audio track number");
+		return 2;
+	}
+
+	if (FormatContext->streams[Index]->codec->codec_type != CODEC_TYPE_AUDIO) {
+		_snprintf(ErrorMsg, MsgSize, "Selected track is not audio");
+		return 3;
+	}
+
+	return 0;
+}
+
+void FFAudioSource::Free(bool CloseCodec) {
+	if (CloseCodec)
+		avcodec_close(CodecContext);
+	av_close_input_file(FormatContext);
+}
+
+FFAudioSource::FFAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize) {
+
+	FormatContext = NULL;
+	AVCodec *Codec = NULL;
+
+	if (av_open_input_file(&FormatContext, SourceFile, NULL, 0, NULL) != 0) {
+		_snprintf(ErrorMsg, MsgSize, "Couldn't open '%s'", SourceFile);
+		throw ErrorMsg;
+	}
+	
+	if (av_find_stream_info(FormatContext) < 0) {
+		Free(false);
+		_snprintf(ErrorMsg, MsgSize, "Couldn't find stream information");
+		throw ErrorMsg;
+	}
+
+	AudioTrack = Track;
+	if (GetTrackIndex(AudioTrack, ErrorMsg, MsgSize)) {
+		Free(false);
+		throw ErrorMsg;
+	}
+
+	Frames = (*TrackIndices)[AudioTrack];
+
+	if (Frames.size() == 0) {
+		Free(false);
+		_snprintf(ErrorMsg, MsgSize, "Audio track contains no frames");
+		throw ErrorMsg;
+	}
+
+	CodecContext = FormatContext->streams[AudioTrack]->codec;
+
+	Codec = avcodec_find_decoder(CodecContext->codec_id);
+	if (Codec == NULL) {
+		Free(false);
+		_snprintf(ErrorMsg, MsgSize, "Audio codec not found");
+		throw ErrorMsg;
+	}
+
+	if (avcodec_open(CodecContext, Codec) < 0) {
+		Free(false);
+		_snprintf(ErrorMsg, MsgSize, "Could not open audio codec");
+		throw ErrorMsg;
+	}
+
+	// Always try to decode a frame to make sure all required parameters are known
+	uint8_t DummyBuf[512];
+	if (GetAudio(DummyBuf, 0, 1, ErrorMsg, MsgSize)) {
+		Free(true);
+		throw ErrorMsg;
+	}
+
+	AP.BitsPerSample = av_get_bits_per_sample_format(CodecContext->sample_fmt);
+	AP.Channels = CodecContext->channels;;
+	AP.Float = AudioFMTIsFloat(CodecContext->sample_fmt);
+	AP.SampleRate = CodecContext->sample_rate;
+	AP.NumSamples = (Frames.back()).SampleStart;
+
+	if (AP.SampleRate <= 0 || AP.BitsPerSample <= 0) {
+		Free(true);
+		_snprintf(ErrorMsg, MsgSize, "Codec returned zero size audio");
+		throw ErrorMsg;
+	}
+}
+
+int FFAudioSource::DecodeNextAudioBlock(uint8_t *Buf, int64_t *Count, char *ErrorMsg, unsigned MsgSize) {
+	const size_t SizeConst = (av_get_bits_per_sample_format(CodecContext->sample_fmt) * CodecContext->channels) / 8;
+	int Ret = -1;
+	*Count = 0;
+	AVPacket Packet;
+
+	while (av_read_frame(FormatContext, &Packet) >= 0) {
+        if (Packet.stream_index == AudioTrack) {
+			uint8_t *Data = Packet.data;
+			int Size = Packet.size;
+
+			while (Size > 0) {
+				int TempOutputBufSize = AVCODEC_MAX_AUDIO_FRAME_SIZE * 10;
+				Ret = avcodec_decode_audio2(CodecContext, (int16_t *)Buf, &TempOutputBufSize, Data, Size);
+
+				if (Ret < 0) {// throw error or something?
+					av_free_packet(&Packet);
+					goto Done;
+				}
+
+				if (Ret > 0) {
+					Size -= Ret;
+					Data += Ret;
+					Buf += TempOutputBufSize;
+					if (SizeConst)
+						*Count += TempOutputBufSize / SizeConst;
+				}
+			}
+
+			av_free_packet(&Packet);
+			goto Done;
+        }
+
+		av_free_packet(&Packet);
+	}
+
+Done:
+	return Ret;
+}
+
+int FFAudioSource::GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) {
+	const size_t SizeConst = (av_get_bits_per_sample_format(CodecContext->sample_fmt) * CodecContext->channels) / 8;
+	size_t CurrentAudioBlock = FFMAX((int64_t)FindClosestAudioKeyFrame(Start) - 50, (int64_t)0);
+	memset(Buf, 0, SizeConst * Count);
+	AVPacket Packet;
+
+	avcodec_flush_buffers(CodecContext);
+	av_seek_frame(FormatContext, AudioTrack, Frames[CurrentAudioBlock].DTS, AVSEEK_FLAG_BACKWARD);
+
+	// Establish where we actually are
+	// Trigger on packet dts difference since groups can otherwise be indistinguishable
+	int64_t LastDTS = - 1;
+	while (av_read_frame(FormatContext, &Packet) >= 0) {
+        if (Packet.stream_index == AudioTrack) {
+			if (LastDTS < 0) {
+				LastDTS = Packet.dts;
+			} else if (LastDTS != Packet.dts) {
+				for (size_t i = 0; i < Frames.size(); i++)
+					if (Frames[i].DTS == Packet.dts) {
+						// The current match was consumed
+						CurrentAudioBlock = i + 1;
+						break;
+					}
+
+				av_free_packet(&Packet);
+				break;
+			}
+		}
+
+		av_free_packet(&Packet);
+	}
+
+	uint8_t *DstBuf = (uint8_t *)Buf;
+	int64_t RemainingSamples = Count;
+	int64_t DecodeCount;
+
+	do {
+		int64_t DecodeStart = Frames[CurrentAudioBlock].SampleStart;
+		int Ret = DecodeNextAudioBlock(DecodingBuffer, &DecodeCount, ErrorMsg, MsgSize);
+		if (Ret < 0) {
+			// FIXME
+			//Env->ThrowError("Bleh, bad audio decoding");
+		}
+		CurrentAudioBlock++;
+
+		int64_t OffsetBytes = SizeConst * FFMAX(0, Start - DecodeStart);
+		int64_t CopyBytes = FFMAX(0, SizeConst * FFMIN(RemainingSamples, DecodeCount - FFMAX(0, Start - DecodeStart)));
+
+		memcpy(DstBuf, DecodingBuffer + OffsetBytes, CopyBytes);
+		DstBuf += CopyBytes;
+
+		if (SizeConst)
+			RemainingSamples -= CopyBytes / SizeConst;
+
+	} while (RemainingSamples > 0 && CurrentAudioBlock < Frames.size());
+
+	return 0;
+}
+
+FFAudioSource::~FFAudioSource() {
+	Free(true);
+}
+
 int MatroskaAudioSource::GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize) {
 	if (Index < 0) {
 		Index = -1;
@@ -69,8 +271,16 @@ int MatroskaAudioSource::GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgS
 	return 0;
 }
 
-void MatroskaAudioSource::Free(bool CloseAudio) {
-
+void MatroskaAudioSource::Free(bool CloseCodec) {
+	if (CS)
+		cs_Destroy(CS);
+	if (MC.ST.fp) {
+		mkv_Close(MF);
+		fclose(MC.ST.fp);
+	}
+	if (CloseCodec)
+		avcodec_close(CodecContext);
+	av_free(CodecContext);
 }
 	
 MatroskaAudioSource::MatroskaAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize) {
@@ -157,7 +367,7 @@ MatroskaAudioSource::MatroskaAudioSource(const char *SourceFile, int Track, Fram
 }
 
 MatroskaAudioSource::~MatroskaAudioSource() {
-
+	Free(true);
 }
 
 int MatroskaAudioSource::GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) {
@@ -175,6 +385,7 @@ int MatroskaAudioSource::GetAudio(void *Buf, int64_t Start, int64_t Count, char
 		int64_t DecodeStart = Frames[CurrentAudioBlock].SampleStart;
 		int Ret = DecodeNextAudioBlock(DecodingBuffer, &DecodeCount, Frames[CurrentAudioBlock].FilePos, Frames[CurrentAudioBlock].FrameSize, ErrorMsg, MsgSize);
 		if (Ret < 0) {
+			// FIXME
 			//Env->ThrowError("Bleh, bad audio decoding");
 		}
 		CurrentAudioBlock++;
diff --git a/FFmpegSource2/ffaudiosource.h b/FFmpegSource2/ffaudiosource.h
index a262b46d6d544543b3f8e0b1841567d99202a145..160cde854872d8051bd6c5f1997bacb634171549 100644
--- a/FFmpegSource2/ffaudiosource.h
+++ b/FFmpegSource2/ffaudiosource.h
@@ -47,27 +47,20 @@ public:
 	virtual int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) = 0;
 };
 
-/*
-class FFmpegAudioSource : public FFAudioBase {
+class FFAudioSource : public AudioBase {
 private:
 	AVFormatContext *FormatContext;
-	AVCodecContext *AudioCodecContext;
-
 	int AudioTrack;
-	FILE *RawCache;
-    unsigned int BufferSize;
-    uint8_t *Buffer;
 
-	bool LoadSampleInfoFromFile(const char *AAudioCacheFile, const char *AAudioCacheFile2, const char *ASource, int AAudioTrack);
-	int DecodeNextAudioBlock(uint8_t *ABuf, int64_t *ACount, uint64_t AFilePos, unsigned int AFrameSize, IScriptEnvironment *Env);
-	int GetTrackIndex(int Index, CodecType ATrackType, IScriptEnvironment *Env);
+	int DecodeNextAudioBlock(uint8_t *Buf, int64_t *Count, char *ErrorMsg, unsigned MsgSize);
+	int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize);
+	void Free(bool CloseCodec);
 public:
-	FFmpegAudioSource(const char *ASource, int AAudioTrack, const char *AAudioCache, const char *AAudioCacheFile2, IScriptEnvironment *Env);
-	~FFmpegAudioSource();
+	FFAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize);
+	~FFAudioSource();
 
-	void __stdcall GetAudio(void* Buf, __int64 Start, __int64 Count, IScriptEnvironment *Env);
+	int GetAudio(void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
 };
-*/
 
 class MatroskaAudioSource : public AudioBase {
 private:
@@ -78,7 +71,7 @@ private:
 
 	int DecodeNextAudioBlock(uint8_t *Buf, int64_t *Count, uint64_t FilePos, unsigned int FrameSize, char *ErrorMsg, unsigned MsgSize);
 	int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize);
-	void Free(bool CloseAudio);
+	void Free(bool CloseCodec);
 public:
 	MatroskaAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize);
 	~MatroskaAudioSource();
diff --git a/FFmpegSource2/ffavisynth.cpp b/FFmpegSource2/ffavisynth.cpp
index 5d5f05d94462f6953b23e4a60b35e0eeec2c9070..3c8eee11505b4cc0331b325ecfffc85f15cc69d0 100644
--- a/FFmpegSource2/ffavisynth.cpp
+++ b/FFmpegSource2/ffavisynth.cpp
@@ -160,8 +160,7 @@ AvisynthAudioSource::AvisynthAudioSource(const char *SourceFile, int Track, Fram
 			case 16: VI.sample_type = SAMPLE_INT16; break;
 			case 24: VI.sample_type = SAMPLE_INT24; break;
 			case 32: VI.sample_type = SAMPLE_INT32; break;
-			default:;
-				// FIXME error here
+			default: Env->ThrowError("FFAudioSource: Bad audio format");
 		}
 	}
 }
diff --git a/FFmpegSource2/ffms.cpp b/FFmpegSource2/ffms.cpp
index 2305ff4cfa165112aee744297e39a3faafc97e85..27c9f1a2c695bc0979e703e860a05e81f81705b5 100644
--- a/FFmpegSource2/ffms.cpp
+++ b/FFmpegSource2/ffms.cpp
@@ -23,6 +23,30 @@
 #include "ffaudiosource.h"
 #include "indexing.h"
 
+FrameInfo::FrameInfo(int64_t DTS, bool KeyFrame) {
+	this->DTS = DTS;
+	this->SampleStart = 0;
+	this->FilePos = 0;
+	this->FrameSize = 0;
+	this->KeyFrame = KeyFrame;
+}
+
+FrameInfo::FrameInfo(int64_t DTS, int64_t SampleStart, bool KeyFrame) {
+	this->DTS = DTS;
+	this->SampleStart = SampleStart;
+	this->FilePos = 0;
+	this->FrameSize = 0;
+	this->KeyFrame = KeyFrame;
+}
+
+FrameInfo::FrameInfo(int64_t SampleStart, int64_t FilePos, unsigned int FrameSize, bool KeyFrame) {
+	this->DTS = 0;
+	this->SampleStart = SampleStart;
+	this->FilePos = FilePos;
+	this->FrameSize = FrameSize;
+	this->KeyFrame = KeyFrame;
+}
+
 FFMS_API(void) FFMS_Init() {
 	static bool InitDone = false;
 	if (!InitDone)
@@ -47,7 +71,7 @@ FFMS_API(VideoBase *) FFMS_CreateVideoSource(const char *SourceFile, int Track,
 FFMS_API(AudioBase *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, char *ErrorMsg, unsigned MsgSize) {
 	try {
 		switch (TrackIndices->Decoder) {
-			//case 0: return new FFVideoSource(SourceFile, Track, TrackIndices, ErrorMsg, MsgSize);
+			case 0: return new FFAudioSource(SourceFile, Track, TrackIndices, ErrorMsg, MsgSize);
 			case 1: return new MatroskaAudioSource(SourceFile, Track, TrackIndices, ErrorMsg, MsgSize);
 			default: 
 				_snprintf(ErrorMsg, MsgSize, "Unsupported format");
@@ -88,6 +112,10 @@ FFMS_API(const AVFrameLite *) FFMS_GetFrame(VideoBase *VB, int n, char *ErrorMsg
 	return (AVFrameLite *)VB->GetFrame(n, ErrorMsg, MsgSize);
 }
 
+FFMS_API(const AVFrameLite *) FFMS_GetFrameByTime(VideoBase *VB, double Time, char *ErrorMsg, unsigned MsgSize) {
+	return (AVFrameLite *)VB->GetFrameByTime(Time, ErrorMsg, MsgSize);
+}
+
 FFMS_API(int) FFMS_GetAudio(AudioBase *AB, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize) {
 	return AB->GetAudio(Buf, Start, Count, ErrorMsg, MsgSize);
 }
diff --git a/FFmpegSource2/ffms.h b/FFmpegSource2/ffms.h
index da7d670488a476d6b98fd5d1efd4283589b49964..9347b20f1d1166e9ff32c59d2872e523b4c34668 100644
--- a/FFmpegSource2/ffms.h
+++ b/FFmpegSource2/ffms.h
@@ -122,14 +122,13 @@ struct TrackTimeBase {
 
 class FrameInfo {
 public:
-	union {
-		int64_t DTS;
-		int64_t SampleStart;
-	};
+	int64_t DTS;
+	int64_t SampleStart;
 	int64_t FilePos;
 	unsigned int FrameSize;
 	bool KeyFrame;
 	FrameInfo(int64_t DTS, bool KeyFrame);
+	FrameInfo(int64_t DTS, int64_t SampleStart, bool KeyFrame);
 	FrameInfo(int64_t SampleStart, int64_t FilePos, unsigned int FrameSize, bool KeyFrame);
 };
 
@@ -166,6 +165,7 @@ FFMS_API(int) FFMS_GetASTrack(AudioBase *AB);
 FFMS_API(const VideoProperties *) FFMS_GetVideoProperties(VideoBase *VB);
 FFMS_API(const AudioProperties *) FFMS_GetAudioProperties(AudioBase *AB);
 FFMS_API(const AVFrameLite *) FFMS_GetFrame(VideoBase *VB, int n, char *ErrorMsg, unsigned MsgSize);
+FFMS_API(const AVFrameLite *) FFMS_GetFrameByTime(VideoBase *VB, double Time, char *ErrorMsg, unsigned MsgSize);
 FFMS_API(int) FFMS_GetAudio(AudioBase *AB, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize);
 FFMS_API(int) FFMS_SetOutputFormat(VideoBase *VB, int TargetFormat, int Width, int Height);
 FFMS_API(void) FFMS_ResetOutputFormat(VideoBase *VB);
diff --git a/FFmpegSource2/ffvideosource.cpp b/FFmpegSource2/ffvideosource.cpp
index 169d339bef61c01f7ba31ed18ebe9df2e7216b62..b60a1ce463cd56eaea7f74399a3048d7bb480c47 100644
--- a/FFmpegSource2/ffvideosource.cpp
+++ b/FFmpegSource2/ffvideosource.cpp
@@ -109,11 +109,9 @@ VideoBase::~VideoBase() {
 	av_free(DecodeFrame);
 }
 
-AVFrame *GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
-	// FIXME
-	//Frames.ClosestFrameFromDTS();
-	//return GetFrame(, ErrorMsg, MsgSize);
-	return NULL;
+AVFrameLite *VideoBase::GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
+	int Frame = Frames.ClosestFrameFromDTS(Time * Frames.TB.Den / Frames.TB.Num);
+	return GetFrame(Frame, ErrorMsg, MsgSize);
 }
 
 int VideoBase::SetOutputFormat(int TargetFormats, int Width, int Height) {
diff --git a/FFmpegSource2/indexing.cpp b/FFmpegSource2/indexing.cpp
index 6c6331e1980c40606e2983f8be2eb2c3075be109..520bae729d12ec2d61dd6ef5921ef28789f34dff 100644
--- a/FFmpegSource2/indexing.cpp
+++ b/FFmpegSource2/indexing.cpp
@@ -27,21 +27,21 @@
 #include "indexing.h"
 #include "wave64writer.h"
 
-class AudioContext {
+class MatroskaAudioContext {
 public:
 	Wave64Writer *W64W;
 	AVCodecContext *CTX;
 	CompressedStream *CS;
 	int64_t CurrentSample;
 
-	AudioContext() {
+	MatroskaAudioContext() {
 		W64W = NULL;
 		CTX = NULL;
 		CS = NULL;
 		CurrentSample = 0;
 	}
 
-	~AudioContext() {
+	~MatroskaAudioContext() {
 		delete W64W;
 		if (CTX) {
 			avcodec_close(CTX);
@@ -52,19 +52,56 @@ public:
 	}
 };
 
-class IndexMemory {
+class FFAudioContext {
+public:
+	Wave64Writer *W64W;
+	AVCodecContext *CTX;
+	int64_t CurrentSample;
+
+	FFAudioContext() {
+		W64W = NULL;
+		CTX = 0;
+		CurrentSample = 0;
+	}
+
+	~FFAudioContext() {
+		delete W64W;
+		if (CTX)
+			avcodec_close(CTX);
+	}
+};
+
+class MatroskaIndexMemory {
 private:
 	int16_t *DecodingBuffer;
-	AudioContext *AudioContexts;
+	MatroskaAudioContext *AudioContexts;
 public:
-	IndexMemory(int Tracks, int16_t *&DecodingBuffer, AudioContext *&AudioContexts) {
+	MatroskaIndexMemory(int Tracks, int16_t *&DecodingBuffer, MatroskaAudioContext *&AudioContexts) {
 		DecodingBuffer = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE*10];
-		AudioContexts = new AudioContext[Tracks];
+		AudioContexts = new MatroskaAudioContext[Tracks];
 		this->DecodingBuffer = DecodingBuffer;
 		this->AudioContexts = AudioContexts;
 	}
 
-	~IndexMemory() {
+	~MatroskaIndexMemory() {
+		delete [] DecodingBuffer;
+		delete [] AudioContexts;
+	}
+};
+
+class FFIndexMemory {
+private:
+	int16_t *DecodingBuffer;
+	FFAudioContext *AudioContexts;
+public:
+	FFIndexMemory(int Tracks, int16_t *&DecodingBuffer, FFAudioContext *&AudioContexts) {
+		DecodingBuffer = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE*10];
+		AudioContexts = new FFAudioContext[Tracks];
+		this->DecodingBuffer = DecodingBuffer;
+		this->AudioContexts = AudioContexts;
+	}
+
+	~FFIndexMemory() {
 		delete [] DecodingBuffer;
 		delete [] AudioContexts;
 	}
@@ -86,7 +123,6 @@ public:
 	}
 };
 
-
 static bool DTSComparison(FrameInfo FI1, FrameInfo FI2) {
 	return FI1.DTS < FI2.DTS;
 }
@@ -157,8 +193,8 @@ static FrameIndex *MakeMatroskaIndex(const char *SourceFile, int IndexMask, int
 	// Audio stuff
 
 	int16_t *db;
-	AudioContext *AudioContexts;
-	IndexMemory IM = IndexMemory(mkv_GetNumTracks(MF), db, AudioContexts);
+	MatroskaAudioContext *AudioContexts;
+	MatroskaIndexMemory IM = MatroskaIndexMemory(mkv_GetNumTracks(MF), db, AudioContexts);
 
 	for (unsigned int i = 0; i < mkv_GetNumTracks(MF); i++) {
 		if (IndexMask & (1 << i) && mkv_GetTrackInfo(MF, i)->Type == TT_AUDIO) {
@@ -217,12 +253,11 @@ static FrameIndex *MakeMatroskaIndex(const char *SourceFile, int IndexMask, int
 		}
 
 		// Only create index entries for video for now to save space
-		if (mkv_GetTrackInfo(MF, Track)->Type == TT_VIDEO)
+		if (mkv_GetTrackInfo(MF, Track)->Type == TT_VIDEO) {
 			(*TrackIndices)[Track].push_back(FrameInfo(StartTime, (FrameFlags & FRAME_KF) != 0));
-
-		if (IndexMask & (1 << Track)) {
-			ReadFrame(FilePos, FrameSize, AudioContexts[Track].CS, MC, ErrorMsg, MsgSize);
+		} else if (mkv_GetTrackInfo(MF, Track)->Type == TT_AUDIO && (IndexMask & (1 << Track))) {
 			(*TrackIndices)[Track].push_back(FrameInfo(AudioContexts[Track].CurrentSample, FilePos, FrameSize, (FrameFlags & FRAME_KF) != 0));
+			ReadFrame(FilePos, FrameSize, AudioContexts[Track].CS, MC, ErrorMsg, MsgSize);
 
 			int Size = FrameSize;
 			uint8_t *Data = MC.Buffer;		
@@ -298,8 +333,8 @@ FrameIndex *MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, const
 	// Audio stuff
 
 	int16_t *db;
-	AudioContext *AudioContexts;
-	IndexMemory IM = IndexMemory(FormatContext->nb_streams, db, AudioContexts);
+	FFAudioContext *AudioContexts;
+	FFIndexMemory IM = FFIndexMemory(FormatContext->nb_streams, db, AudioContexts);
 
 	for (unsigned int i = 0; i < FormatContext->nb_streams; i++) {
 		if (IndexMask & (1 << i) && FormatContext->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
@@ -342,55 +377,54 @@ FrameIndex *MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, const
 		}
 
 		// Only create index entries for video for now to save space
-		if (FormatContext->streams[Packet.stream_index]->codec->codec_type == CODEC_TYPE_VIDEO)
+		if (FormatContext->streams[Packet.stream_index]->codec->codec_type == CODEC_TYPE_VIDEO) {
 			(*TrackIndices)[Packet.stream_index].push_back(FrameInfo(Packet.dts, (Packet.flags & PKT_FLAG_KEY) ? 1 : 0));
+		} else if (FormatContext->streams[Packet.stream_index]->codec->codec_type == CODEC_TYPE_AUDIO && (IndexMask & (1 << Packet.stream_index))) {
+			(*TrackIndices)[Packet.stream_index].push_back(FrameInfo(Packet.dts, AudioContexts[Packet.stream_index].CurrentSample, (Packet.flags & PKT_FLAG_KEY) ? 1 : 0));
+			AVCodecContext *AudioCodecContext = FormatContext->streams[Packet.stream_index]->codec;
+			int Size = Packet.size;
+			uint8_t *Data = Packet.data;
 
-		if (IndexMask & (1 << Packet.stream_index)) {
-				AVCodecContext *AudioCodecContext = FormatContext->streams[Packet.stream_index]->codec;
-				int Size = Packet.size;
-				uint8_t *Data = Packet.data;
-
-				while (Size > 0) {
-					int dbsize = AVCODEC_MAX_AUDIO_FRAME_SIZE*10;
-					int Ret = avcodec_decode_audio2(AudioCodecContext, db, &dbsize, Data, Size);
-					if (Ret < 0) {
-						if (IgnoreDecodeErrors) {
-							(*TrackIndices)[Packet.stream_index].clear();
-							IndexMask &= ~(1 << Packet.stream_index);					
-							break;
-						} else {
-							_snprintf(ErrorMsg, MsgSize, "Audio decoding error");
-							delete TrackIndices;
-							return NULL;
-						}
+			while (Size > 0) {
+				int dbsize = AVCODEC_MAX_AUDIO_FRAME_SIZE*10;
+				int Ret = avcodec_decode_audio2(AudioCodecContext, db, &dbsize, Data, Size);
+				if (Ret < 0) {
+					if (IgnoreDecodeErrors) {
+						(*TrackIndices)[Packet.stream_index].clear();
+						IndexMask &= ~(1 << Packet.stream_index);					
+						break;
+					} else {
+						_snprintf(ErrorMsg, MsgSize, "Audio decoding error");
+						delete TrackIndices;
+						return NULL;
 					}
+				}
 
-					if (Ret > 0) {
-						Size -= Ret;
-						Data += Ret;
-					}
+				if (Ret > 0) {
+					Size -= Ret;
+					Data += Ret;
+				}
+
+				if (dbsize > 0)
+					AudioContexts[Packet.stream_index].CurrentSample += (dbsize * 8) / (av_get_bits_per_sample_format(AudioCodecContext->sample_fmt) * AudioCodecContext->channels);
 
-					// FIXME currentsample calculation here
-					if (dbsize > 0)
-						dbsize = dbsize;
-
-					if (dbsize > 0 && (DumpMask & (1 << Packet.stream_index))) {
-						// Delay writer creation until after an audio frame has been decoded. This ensures that all parameters are known when writing the headers.
-						if (!AudioContexts[Packet.stream_index].W64W) {
-							char ABuf[50];
-							std::string WN(AudioFile);
-							int Offset = (Packet.dts * FormatContext->streams[Packet.stream_index]->time_base.num)
-								/ (double)(FormatContext->streams[Packet.stream_index]->time_base.den * 1000);
-							_snprintf(ABuf, sizeof(ABuf), ".%02d.delay.%d.w64", Packet.stream_index, Offset);
-							WN += ABuf;
-							
-							AudioContexts[Packet.stream_index].W64W = new Wave64Writer(WN.c_str(), av_get_bits_per_sample_format(AudioCodecContext->sample_fmt),
-								AudioCodecContext->channels, AudioCodecContext->sample_rate, AudioFMTIsFloat(AudioCodecContext->sample_fmt));
-						}
-
-						AudioContexts[Packet.stream_index].W64W->WriteData(db, dbsize);
+				if (dbsize > 0 && (DumpMask & (1 << Packet.stream_index))) {
+					// Delay writer creation until after an audio frame has been decoded. This ensures that all parameters are known when writing the headers.
+					if (!AudioContexts[Packet.stream_index].W64W) {
+						char ABuf[50];
+						std::string WN(AudioFile);
+						int Offset = (Packet.dts * FormatContext->streams[Packet.stream_index]->time_base.num)
+							/ (double)(FormatContext->streams[Packet.stream_index]->time_base.den * 1000);
+						_snprintf(ABuf, sizeof(ABuf), ".%02d.delay.%d.w64", Packet.stream_index, Offset);
+						WN += ABuf;
+						
+						AudioContexts[Packet.stream_index].W64W = new Wave64Writer(WN.c_str(), av_get_bits_per_sample_format(AudioCodecContext->sample_fmt),
+							AudioCodecContext->channels, AudioCodecContext->sample_rate, AudioFMTIsFloat(AudioCodecContext->sample_fmt));
 					}
+
+					AudioContexts[Packet.stream_index].W64W->WriteData(db, dbsize);
 				}
+			}
 		}
 
 		av_free_packet(&Packet);
@@ -457,20 +491,6 @@ FrameIndex *ReadIndex(const char *IndexFile, char *ErrorMsg, unsigned MsgSize) {
 	return TrackIndices;
 }
 
-FrameInfo::FrameInfo(int64_t DTS, bool KeyFrame) {
-	this->DTS = DTS;
-	this->FilePos = 0;
-	this->FrameSize = 0;
-	this->KeyFrame = KeyFrame;
-}
-
-FrameInfo::FrameInfo(int64_t SampleStart, int64_t FilePos, unsigned int FrameSize, bool KeyFrame) {
-	this->SampleStart = SampleStart;
-	this->FilePos = FilePos;
-	this->FrameSize = FrameSize;
-	this->KeyFrame = KeyFrame;
-}
-
 int FrameInfoVector::WriteTimecodes(const char *TimecodeFile, char *ErrorMsg, unsigned MsgSize) {
 	std::ofstream Timecodes(TimecodeFile, std::ios::out | std::ios::trunc);
 
@@ -516,13 +536,13 @@ int FrameInfoVector::FindClosestKeyFrame(int Frame) {
 }
 
 FrameInfoVector::FrameInfoVector() {
-	TT = 0;
-	TB.Num = 0; 
-	TB.Den = 0;
+	this->TT = 0;
+	this->TB.Num = 0; 
+	this->TB.Den = 0;
 }
 
 FrameInfoVector::FrameInfoVector(int Num, int Den, int TT) {
 	this->TT = TT;
-	TB.Num = Num; 
-	TB.Den = Den;
+	this->TB.Num = Num; 
+	this->TB.Den = Den;
 }
diff --git a/FFmpegSource2/indexing.h b/FFmpegSource2/indexing.h
index 886599361dd43f943f1af9b37613451070c86858..b9b4e461ab9e8dcf44a8c53ff1bc9af48e6649ff 100644
--- a/FFmpegSource2/indexing.h
+++ b/FFmpegSource2/indexing.h
@@ -33,7 +33,7 @@ extern "C" {
 #include "utils.h"
 #include "ffms.h"
 
-#define INDEXVERSION 7
+#define INDEXVERSION 8
 #define INDEXID 0x53920873
 
 struct IndexHeader {