changeset 2455:51d4f38aca6c

audio through OpenAL (begining)
author Ritor1
date Fri, 25 Jul 2014 17:49:20 +0600
parents 16f0278279a5
children 83174b7b3763
files AudioPlayer.cpp AudioPlayer.h Events.cpp MediaPlayer.cpp MediaPlayer.h mm7_2.cpp
diffstat 6 files changed, 99 insertions(+), 153 deletions(-) [+]
line wrap: on
line diff
--- a/AudioPlayer.cpp	Fri Jul 25 15:47:11 2014 +0600
+++ b/AudioPlayer.cpp	Fri Jul 25 17:49:20 2014 +0600
@@ -607,9 +607,9 @@
         {
           AIL_init_sample(pMixerChannels[j].hSample);
           char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
-          if (sound_data_id == 0)  p = p + 4;//for RIFF
-		  if ( eSoundID == 75 )// Ritor1: include +7 for pSounds[20]
-			  p = p + 7;
+          //if (sound_data_id == 0)  p = p + 4;//for RIFF
+		  //if ( eSoundID == 75 )// Ritor1: include +7 for pSounds[20]
+			  //p = p + 7;
           AIL_set_sample_file(pMixerChannels[j].hSample, p, -1);
           if ( sample_volume == 10000 )
             sample_volume = uMasterVolume;
@@ -2141,15 +2141,8 @@
 //----- (004AB8CE) --------------------------------------------------------
 void AudioPlayer::Initialize()
 {
-  //AudioPlayer *v2; // esi@1
   int v3; // ebx@1
-  //_DIG_DRIVER *v4; // eax@1
   _PROVIDER *v6; // eax@9
-  //HWND v7; // ST00_4@9
-  //MixerChannel *pChannel; // edi@14
-//  _SAMPLE *v9; // eax@15
-  //_REDBOOK *v10; // eax@19
-  //int v11; // ecx@21
   int v12; // [sp+Ch] [bp-Ch]@9
   char *Str1; // [sp+10h] [bp-8h]@6
   int v14; // [sp+14h] [bp-4h]@5
--- a/AudioPlayer.h	Fri Jul 25 15:47:11 2014 +0600
+++ b/AudioPlayer.h	Fri Jul 25 17:49:20 2014 +0600
@@ -1,6 +1,6 @@
 #pragma once
 #include "OSAPI.h"
-
+#include "MediaPlayer.h"
 
 
 
@@ -41,7 +41,7 @@
 
 
 /*   26 */
-#pragma pack(push, 1)
+/*#pragma pack(push, 1)
 struct SoundHeader
 {
   char pSoundName[40];
@@ -49,7 +49,7 @@
   unsigned int uCompressedSize;
   unsigned int uDecompressedSize;
 };
-#pragma pack(pop)
+#pragma pack(pop)*/
 
 /*   27 */
 #pragma pack(push, 1)
@@ -169,8 +169,8 @@
   void PlaySound(SoundID eSoundID, signed int a3, unsigned int uNumRepeats, signed int a5, signed int a6, int a7, float uVolume, int sPlaybackRate);
   void UpdateSounds();
   void StopChannels(int uStartChannel, int uEndChannel);
-  void LoadAudioSnd();
-  void Initialize();
+  void LoadAudioSnd();//
+  void Initialize();//
   void CheckA3DSupport(bool query);
   void Release();
   void FreeChannel(MixerChannel *pChannel);
--- a/Events.cpp	Fri Jul 25 15:47:11 2014 +0600
+++ b/Events.cpp	Fri Jul 25 17:49:20 2014 +0600
@@ -287,7 +287,6 @@
 //----- (0044684A) --------------------------------------------------------
 void EventProcessor(int uEventID, int targetObj, int canShowMessages, int entry_line)
 {
-//  unsigned int v3; // eax@5
   signed int v4; // esi@7
   int v11; // eax@14
   char *v12; // eax@15
@@ -302,60 +301,22 @@
   unsigned __int16 v24; // ax@45
   LevelDecoration *v26; // eax@55
   int v27; // eax@57
-//  int v28; // ecx@57
   int pEventID; // eax@58
   int pNPC_ID; // ecx@58
   int pIndex; // esi@58
   NPCData *pNPC; // ecx@58
-//  int v34; // esi@59
-//  int v35; // esi@60
-//  int v36; // esi@61
-//  int v37; // esi@62
   int v38; // eax@78
   int v39; // ecx@78
   int v42; // eax@84
   int v43; // ecx@84
-//  void *v46; // eax@91
-//  GUIWindow *v47; // eax@93
   GUIButton *v48; // ecx@93
   GUIButton *v49; // esi@94
-//  char v50; // al@100
-//  Player *v51; // esi@103
-//  Player *v52; // ecx@106
-//  int v53; // ecx@107
-//  char v54; // al@111
-//  Player *v55; // esi@114
-//  Player *v56; // ecx@117
-//  int v57; // ecx@118
   signed int pValue; // ebp@124
   Player *pPlayer; // esi@125
-//  int v60; // eax@126
-//  int v61; // edx@133
-//  int v62; // eax@139
-//  int v63; // ebp@145
-//  signed int v64; // edi@146
-//  unsigned int v65; // edx@148
-//  Player *v66; // ecx@148
-//  int v67; // esi@148
-//  signed int v68; // eax@151
-//  int v69; // esi@151
-//  Player *v70; // ecx@158
-//  unsigned int v71; // eax@159
-//  int v72; // esi@159
-//  signed int v73; // eax@162
-//  int v74; // esi@162
-//  int v75; // edx@172
-//  Player *v76; // esi@173
-//  signed int v77; // ebp@186
-//  int v78; // edx@186
-//  Player *v79; // esi@187
-//  Player *v82; // esi@201
   int v83; // eax@212
   int v84; // ebp@220
   int v90; // eax@243
   const char *v91; // ecx@247
-//  int v92; // eax@251
-//  char *v93; // eax@252
   int v94; // ecx@262
   int v95; // ebp@262
   int v96; // edx@262
@@ -364,17 +325,10 @@
   const char *v99; // esi@267
   int v100; // edx@267
   unsigned int v102; // esi@281
-//  int v103; // edi@284
   int v104; // eax@288
-//  int v105; // edx@294
   int v106; // [sp-20h] [bp-4C8h]@278
   signed int v109; // [sp-14h] [bp-4BCh]@278
   signed int v110; // [sp-10h] [bp-4B8h]@278
-//  int v113; // [sp-8h] [bp-4B0h]@106
-//  int v114; // [sp-8h] [bp-4B0h]@117
-//  int v117; // [sp-4h] [bp-4ACh]@106
-//  int v118; // [sp-4h] [bp-4ACh]@117
-//  int v121; // [sp-4h] [bp-4ACh]@294
   int curr_seq_num; // [sp+10h] [bp-498h]@4
   int v126; // [sp+1Ch] [bp-48Ch]@262
   int player_choose; // [sp+20h] [bp-488h]@4
@@ -397,7 +351,7 @@
   v133 = 0;
   EvtTargetObj = targetObj;
   dword_5B65C4_cancelEventProcessing = 0;
-  /*if ( uEventID == 114 )//чтобы проверить скрипт
+  /*if ( uEventID == 114 )//for test script
   {
     if (!lua->DoFile("out01.lua"))
       Log::Warning(L"Error opening out01.lua\n");
@@ -465,7 +419,7 @@
         v128 = pCurrentScreen;
         strcpy(Str, Source);
         v16 = RemoveQuotes(Str);
-		pMediaPlayer->GlobalMovieLoop(v16, 0/*, _evt->v5*/);
+		pMediaPlayer->FullscreenMovieLoop(v16, 0/*, _evt->v5*/);
         if ( !_stricmp(v16, "arbiter good") )
         {
           pParty->alignment = PartyAlignment_Good;
--- a/MediaPlayer.cpp	Fri Jul 25 15:47:11 2014 +0600
+++ b/MediaPlayer.cpp	Fri Jul 25 17:49:20 2014 +0600
@@ -39,47 +39,47 @@
 void PlayAudio(const wchar_t * pFilename);
 void LoadMovie(const char *);
  
-class MemoryStream //класс для работы с памятью
+class MemoryStream 
 {
   public:
-    inline MemoryStream(void *data, size_t data_size)//inline - вставка прямо в код, MemoryStream - явный конструктор
+    inline MemoryStream(void *data, size_t data_size)
     {
       this->data_size = data_size;
       this->data = data;
       this->current_pos = 0;
     }
-    inline MemoryStream() //конструктор по умолчанию
+    inline MemoryStream()
     {
       this->data_size = 0;
       this->data = nullptr;
       this->current_pos = 0;
     }
 
-    inline ~MemoryStream()//деструктор по умолчанию
+    inline ~MemoryStream()
     {
       //Log::Warning(L"Destructor: data delete %u", data);
       if (data)
         delete [] data;
     }
 
-    inline size_t Write(void *buffer, size_t num_bytes)//запись в поток
+    inline size_t Write(void *buffer, size_t num_bytes)
     {
       if (!data)
       {
         data_size = 32 + num_bytes;
-        data = new char[data_size];//выделение памяти для data
+        data = new char[data_size];
         //Log::Warning(L"new data %u", data);
         current_pos = 0;
       }
-      else if (current_pos + num_bytes >= data_size) //если выделенного буфера недостаточно
+      else if (current_pos + num_bytes >= data_size)
       {
         int  new_data_size = data_size + num_bytes + data_size / 8 + 4;
-        auto new_data = new char[new_data_size];//выделение памяти
+        auto new_data = new char[new_data_size];
         //Log::Warning(L"new new_data %u", new_data);
 
-        memcpy(new_data, data, data_size);	  //Invalid partial memory access
+        memcpy(new_data, data, data_size);
         //Log::Warning(L"data delete %u", data);
-        delete [] data;//удаление памяти под data
+        delete [] data;
 
         data_size = new_data_size;
         data = new_data;
@@ -89,7 +89,7 @@
       return num_bytes;
     }
 
-    inline size_t Read(void *buffer, size_t num_bytes) //чтение из потока
+    inline size_t Read(void *buffer, size_t num_bytes)
     {
       size_t read_size = min(num_bytes, data_size - current_pos);
       if (read_size)
@@ -100,16 +100,16 @@
       return read_size;
     }
 
-    inline void Reset()//сброс
+    inline void Reset()
     {
       current_pos = 0;
     }
-    inline void SeekToEnd()//прыжок в конец
+    inline void SeekToEnd()
     {
       current_pos = data_size;
     }
 
-    inline size_t Unwind(size_t bytes)//зациклить???
+    inline size_t Unwind(size_t bytes)
     {
       if (bytes > current_pos)
         current_pos = 0;
@@ -188,7 +188,6 @@
     if (dec_ctx)
     {
 	  // Close the codec
-      // закрытие кодека
       avcodec_close(dec_ctx);
 	  Log::Warning(L"close decoder context file\n");
       dec_ctx = nullptr;
@@ -202,7 +201,7 @@
   AVCodecContext  *dec_ctx;
 };
 
-struct AVAudioStream: public AVStreamWrapper//структура AVAudioStreem производная от структуры AVStreemWrapper
+struct AVAudioStream: public AVStreamWrapper
 {
   inline AVAudioStream():AVStreamWrapper()
   {
@@ -226,23 +225,17 @@
 
 static bool av_open_stream(AVFormatContext *format_ctx, AVMediaType type, AVStreamWrapper *out_stream)
 {
-  // найдем первый stream
   int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0);
   if (stream_idx >= 0)
   {
     auto stream = format_ctx->streams[stream_idx];
-    //Информация о кодеке в потоке называется «контекстом кодека» (AVCodecContext).
-    //Используя эту информацию, мы можем найти необходимый кодек (AVCodec) и открыть его.
-	// получаемм кодек
     auto dec_ctx = stream->codec;
 
 	// Find the decoder for the video stream
-    // ищем декодер
     auto dec = avcodec_find_decoder(dec_ctx->codec_id);
     if (dec)
     {
 	  // Open codec
-      // открываем кодек
       if (avcodec_open2(dec_ctx, dec, nullptr) >= 0)
       {
         out_stream->type = type;
@@ -252,13 +245,13 @@
         out_stream->dec_ctx = dec_ctx;
         return true;
       }
-      fprintf(stderr, "ffmpeg: Could not open codec\n");// Не открылся кодек
+      fprintf(stderr, "ffmpeg: Could not open codec\n");
 	  return false;
     }
-    fprintf(stderr, "ffmpeg: Unable to open codec\n");// Кодек не найден
+    fprintf(stderr, "ffmpeg: Unable to open codec\n");
 	return false;
   }
-  fprintf(stderr, "ffmpeg: Didn't find a stream\n");// Не найден stream
+  fprintf(stderr, "ffmpeg: Didn't find a stream\n");
   return false;	
 }
 
@@ -268,7 +261,7 @@
     return Error("Audio stream not found"), false;
   
   // we support only 2-channel audio for now
-  //if (out_stream->dec_ctx->channels != 2)//закомментировал потому что при воспроизведении jvc.bik вылетает на этом месте
+  //if (out_stream->dec_ctx->channels != 2)
   //{
    // out_stream->Release();
    // return Error("Unsupported number of channels: %u", out_stream->dec_ctx->channels), false;
@@ -372,7 +365,6 @@
   volatile int decoded = false;
   do
   {
-    //Декодирование аудио-пакета осуществляется функцией avcodec_decode_audio4
     if (avcodec_decode_audio4(dec_ctx, avframe, (int *)&decoded, avpacket) < 0)	//Uninitialized portail memory access
     {
       log("Cannot decode audio frame\n");
@@ -437,10 +429,6 @@
    // if sample rate < 44100, frame size is 4096 samples
    // else, frame size is 8192 samples
 
- //сжимает аудио в куски различных размеров в зависимости от частоты дискретизации:
-   //если частота дискретизации < 22050, размер кадра составляет 2048 самплов
-   //если частота дискретизации < 44100, размер кадра составляет 4096 самплов
-   //или, размер кадра составляет 8192 самплов
 
   /* determine frame length */
   if (dec_ctx->sample_rate < 22050)
@@ -450,7 +438,6 @@
   else
     frame_len_bits = 11;
 
-  //проверка количества каналов (не меньше 1 и не больше 2)
   if (dec_ctx->channels < 1 || dec_ctx->channels > 2) 
   {
         av_log(dec_ctx, AV_LOG_ERROR, "invalid number of channels: %d\n", dec_ctx->channels);
@@ -479,7 +466,6 @@
 	  frame_len     = 1 << frame_len_bits;                          //2048
 
 	  //a frame is windowed with the previous frame; the size of the window is frame size / 16 
-	  //кадр оконный с предыдущего кадра;Размер окна = размер кадра / 16
       overlap_len   = frame_len / 16;                               //128
       block_size    = (frame_len - overlap_len) * channels;         //1920
 
@@ -487,9 +473,6 @@
 	  //initialize an array of band frequencies corresponding to an array of 25 critical frequencies (same as WMA, apparently),
 	  // any for which the critical frequencies are less than half the sample rate 
 
-	  //вычислить половину частоты дискретизации(частота дискретизации + 1) / 2;
-	  //инициализировать массив группы частот, соответствующих массиву 25 критических частот (аналогично WMA, очевидно),
-	  // любой, для которых критические частоты в два раза меньше частота дискретизации
       sample_rate_half = (sample_rate + 1) / 2;	                    //22050
       if (dec_ctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
          root = 2.0 / (sqrt(float(frame_len)) * 32768.0);
@@ -610,10 +593,6 @@
 {
   out_audio_stream->Reset();
 
-  //Чтение аудио данных.
-  //Данные из файла читаются пакетами (AVPacket), а для воспроизведения используется фрейм (AVFrame).
-
-  //Выделим память для фрейма
   AVFrame  *frame = avcodec_alloc_frame();
 
   AVPacket *packet = new AVPacket;
@@ -622,11 +601,9 @@
   int num_audio_frames = 0;
   int num_audio_samples = 0;
 
-  //чтение пакетов
   while (av_read_frame(format_ctx, packet) >= 0)
   {
 	// Is this a packet from the audio stream?
-    //Принадлежит ли пакет к аудиопотоку
     if (packet->stream_index != audio_stream_idx)
     {
       //log("Suspicious stream id %u in %s", packet->stream_index, filenamea);
@@ -634,7 +611,6 @@
     }
 
 	// Decode audio frame
-	//Декодируем аудио фрейм
     int num_samples_decoded;
     DecodeAudioFrame(dec_ctx, packet, frame, out_audio_stream, &num_samples_decoded);
 
@@ -644,7 +620,6 @@
   *out_num_audio_frames = num_audio_frames;
   *out_num_audio_samples = num_audio_samples;
 
-  //Освободить память выделенную для фрейма
   avcodec_free_frame(&frame);
   delete frame;
   av_free_packet(packet);
@@ -653,10 +628,10 @@
   return true;
 }
 
-class Track: public Media::ITrack//класс производная от базового Media::ITrack
+class Track: public Media::ITrack
 {
   public:
-    inline Track()//прямая вставка в код
+    inline Track()
     {
       this->format_ctx = nullptr;
       this->audio_num_samples = 0;
@@ -672,36 +647,25 @@
       audio.Release();
       if (format_ctx)
       {
-        // закрытие контекста файла
         av_close_input_file(format_ctx);
 		Log::Warning(L"close audio format context file\n");
         format_ctx = nullptr;
       }
     }
 
-    bool LoadAudio(const wchar_t *filename) //Загрузка из папки	для mp3
+    bool LoadAudio(const wchar_t *filename)
     {
       char filenamea[1024];
       sprintf(filenamea, "%S", filename);
       // Open audio file
-      //откроем входной файл(Шаг 2)
-      //Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре
-      //AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует 
-      //автоматическое определение параметров.
       if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
       {
         // Retrieve stream information
-        //Т.к. avformat_open_input читает только заголовок файла, то следующим шагом нужно получить информацию о потоках
-        //в файле. Это делается функцией avformat_find_stream_info.
         if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
         {
           // Dump information about file onto standard error
-          //После этого format_context->streams содержит все существующие потоки файла. 
-          //Их количество равно format_context->nb_streams.
-          //Вывести подробную информацию о файле и обо всех потоках можно функцией av_dump_format.
           av_dump_format(format_ctx, 0, filenamea, 0);
 
-		  //Открыть поток
           if (!av_open_audio_stream(format_ctx, &audio))
           {
             Error("Cannot open strack: %s", filenamea);
@@ -712,7 +676,6 @@
           int          num_audio_frames;
           int          num_audio_samples;
 
-		  //Загрузить аудио трек
           if (LoadAudioTrack(format_ctx, audio.dec_ctx, audio.stream_idx, &audio_plain_data, &num_audio_frames, &num_audio_samples))
           {
             /*#ifdef _DEBUG
@@ -736,10 +699,10 @@
           }
         }
         Release();
-        fprintf(stderr, "ffmpeg: Unable to find stream info\n"); //Не найден поток
+        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
         return false;
       }
-      fprintf(stderr, "ffmpeg: Unable to open input file\n"); //Не может открыть файл
+      fprintf(stderr, "ffmpeg: Unable to open input file\n");
       return false;
     }
 
@@ -803,7 +766,6 @@
       if (format_ctx)
       {
 		// Close the video file
-        // закрытие контекста файла(видео файла)
         av_close_input_file(format_ctx);
 		Log::Warning(L"close video format context file\n");
         format_ctx = nullptr;
@@ -977,7 +939,6 @@
           last_resampled_frame_num = desired_frame_number;
           memcpy(last_resampled_frame_data, rescaled_data, sizeof(rescaled_data));
           memcpy(last_resampled_frame_linesize, rescaled_linesize, sizeof(rescaled_linesize));
-          //av_freep(&rescaled_data[0]);
         }
       }
       else
@@ -1043,6 +1004,8 @@
 }
 
 
+//for video/////////////////////////////////////////////////////////////////
+
 //----- (004BE9D8) --------------------------------------------------------
 void MPlayer::Initialize(OSWindow *target_window)
 {
@@ -1091,7 +1054,7 @@
 }
 
 //----- (004BF411) --------------------------------------------------------
-void MPlayer::OpenGlobalMovie(const char *pFilename, unsigned int bLoop/*, int ScreenSizeFlag*/)
+void MPlayer::OpenFullscreenMovie(const char *pFilename, unsigned int bLoop/*, int ScreenSizeFlag*/)
 {
   if (!this->bPlaying_Movie)
   {
@@ -1133,7 +1096,7 @@
 }
 
 //----- (004BE70E) --------------------------------------------------------
-void MPlayer::GlobalMovieLoop(const char *pMovieName, int a2/*, int ScreenSizeFlag, int a4*/)
+void MPlayer::FullscreenMovieLoop(const char *pMovieName, int a2/*, int ScreenSizeFlag, int a4*/)
 {
   int v4; // ebp@1
   MSG Msg; // [sp+Ch] [bp-1Ch]@12
@@ -1146,7 +1109,7 @@
     if ( a2 == 2 )
       v4 = 0;
     ShowCursor(0);
-    OpenGlobalMovie(pMovieName, 0);
+    OpenFullscreenMovie(pMovieName, 0);
     bPlaying_Movie = 1;
     field_44 = v4;
     pRenderer->ClearTarget(0);
@@ -1299,7 +1262,7 @@
   if ( this->uMovieType == 1 )
     OpenHouseMovie(Source, LOBYTE(this->bLoopPlaying));
   else if ( this->uMovieType == 2 )
-    OpenGlobalMovie(Source, LOBYTE(this->bLoopPlaying));
+    OpenFullscreenMovie(Source, LOBYTE(this->bLoopPlaying));
   else
     __debugbreak();
 }
@@ -1357,7 +1320,6 @@
   pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, client_width, client_height);
 }
 
-
 //----- (004BF794) --------------------------------------------------------
 void MPlayer::ShowMM7IntroVideo_and_LoadingScreen()
 {
@@ -1438,6 +1400,9 @@
   return li.QuadPart;
 }
 
+//for video//////////////////////////////////////////////////////////////////
+
+
 
 IMovie *MPlayer::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
 {
@@ -1453,6 +1418,35 @@
 	return nullptr;
 }
 
+void MovieRelease()
+{
+  movie->Release();
+  delete movie;
+  Log::Warning(L"delete dynamic memory for movie\n");
+  movie = nullptr;
+}
+
+
+//for audio///////////////////////////////////////////////////////
+//----- (004AB818) --------------------------------------------------------
+void MPlayer::LoadAudioSnd()
+{
+  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3
+
+  hAudioSnd = CreateFileA("Sounds\\Audio.snd", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0);
+  if (hAudioSnd == INVALID_HANDLE_VALUE)
+  {
+    Log::Warning(L"Can't open file: %s", L"Sounds\\Audio.snd");
+    return;
+  }
+
+  ReadFile(hAudioSnd, &uNumSoundHeaders, 4, &NumberOfBytesRead, 0);
+  pSoundHeaders = nullptr;
+  pSoundHeaders = (SoundHeader *)malloc(52 * uNumSoundHeaders + 2);
+  ReadFile(hAudioSnd, pSoundHeaders, 52 * uNumSoundHeaders, &NumberOfBytesRead, 0);
+}
+//for audio///////////////////////////////////////////////////////
+
 void av_logger(void *, int, const char *format, va_list args)
 {
   va_list va;
@@ -1467,7 +1461,6 @@
 MPlayer::MPlayer()
 {
   bPlaying_Movie = false;
-  //pSmackMovieBlit = nullptr;
 
   static int libavcodec_initialized = false;
 
@@ -1483,7 +1476,6 @@
   }
 
   bStopBeforeSchedule = false;
-//  pResetflag = 0;
   pMovie_Track = nullptr;
 
   if (!provider)
@@ -1492,6 +1484,7 @@
 	Log::Warning(L"allocation dynamic memory for provider\n");
     provider->Initialize();
   }
+  LoadAudioSnd();
 }
 
 MPlayer::~MPlayer()
@@ -1519,10 +1512,3 @@
   Movie_track->Play();
 }
 
-void MovieRelease()
-{
-  movie->Release();
-  delete movie;
-  Log::Warning(L"delete dynamic memory for movie\n");
-  movie = nullptr;
-}
\ No newline at end of file
--- a/MediaPlayer.h	Fri Jul 25 15:47:11 2014 +0600
+++ b/MediaPlayer.h	Fri Jul 25 17:49:20 2014 +0600
@@ -39,6 +39,13 @@
   char pVideoName[40];
   unsigned int uFileOffset;
 };
+struct SoundHeader
+{
+  char pSoundName[40];
+  unsigned int uFileOffset;
+  unsigned int uCompressedSize;
+  unsigned int uDecompressedSize;
+};
 
 enum MovieType
 {
@@ -101,18 +108,18 @@
       DWORD time_video_begin;
       int current_movie_width;
       int current_movie_height;
-
-      HANDLE hVidFile;
+	  HANDLE hVidFile;
       int uSize;
       int uOffset;
 
       void Initialize(OSWindow *window);
 
-      void OpenGlobalMovie(const char *pFilename, unsigned int bLoop);
+      void OpenFullscreenMovie(const char *pFilename, unsigned int bLoop);
       void OpenHouseMovie(const char *pMovieName, unsigned int a3_1);
 
       void LoadMovie(const char *);
       void SelectMovieType();
+
       inline void PlayFullscreenMovie(MovieType movie_type, bool bShowMouseAfterPlayback)
       {
         extern unsigned int bNoVideo;
@@ -120,21 +127,20 @@
 
         switch (movie_type)
         {
-          case MOVIE_3DOLogo: GlobalMovieLoop("3dologo", 0);        break;
-          case MOVIE_NWCLogo: GlobalMovieLoop("new world logo", 0); break;
-          case MOVIE_JVC:     GlobalMovieLoop("jvc", 0);            break;
-          case MOVIE_Intro:   GlobalMovieLoop("Intro", 0);          break;
-          case MOVIE_Emerald: GlobalMovieLoop("Intro Post", 0);     break;
-          case MOVIE_Death:   GlobalMovieLoop("losegame", 2);       break;
-          case MOVIE_Outro:   GlobalMovieLoop("end_seq1", 20);      break;
+          case MOVIE_3DOLogo: FullscreenMovieLoop("3dologo", 0);        break;
+          case MOVIE_NWCLogo: FullscreenMovieLoop("new world logo", 0); break;
+          case MOVIE_JVC:     FullscreenMovieLoop("jvc", 0);            break;
+          case MOVIE_Intro:   FullscreenMovieLoop("Intro", 0);          break;
+          case MOVIE_Emerald: FullscreenMovieLoop("Intro Post", 0);     break;
+          case MOVIE_Death:   FullscreenMovieLoop("losegame", 2);       break;
+          case MOVIE_Outro:   FullscreenMovieLoop("end_seq1", 20);      break;
 
           default:
             Error("Invalid movie requested: %u", movie_type);
           break;
         }
       }
-
-	  void GlobalMovieLoop(const char *pMovieName, int a2);
+	  void FullscreenMovieLoop(const char *pMovieName, int a2);
       void HouseMovieLoop();
 
       void ShowMM7IntroVideo_and_LoadingScreen();
@@ -144,6 +150,14 @@
       IMovie *LoadMovie(const wchar_t *name, int width, int height, int cache_ms);
       IMovie *LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height);
 
+	  //for audio////////////////////////////////////
+	  HANDLE hAudioSnd;
+	  unsigned int uNumSoundHeaders;
+	  struct SoundHeader *pSoundHeaders;
+
+	  void LoadAudioSnd();
+	  ///////////////////////////////////////////////
+
 
       ITrack *LoadTrack(const wchar_t *name);
 
--- a/mm7_2.cpp	Fri Jul 25 15:47:11 2014 +0600
+++ b/mm7_2.cpp	Fri Jul 25 17:49:20 2014 +0600
@@ -2080,7 +2080,6 @@
         DeleteCCharFont();
         bFlashQuestBook = true;
         pMediaPlayer->PlayFullscreenMovie(MOVIE_Emerald, true);
-        //pGame->pCShow->PlayMovie(MOVIE_Emerald, 0);
         SaveNewGame();
         if (bNoMargareth)
           _449B7E_toggle_bit(pParty->_quest_bits, PARTY_QUEST_EMERALD_MARGARETH_OFF, 1);