diff --git a/core/audio_display.cpp b/core/audio_display.cpp index 2c593a4c3..46677f090 100644 --- a/core/audio_display.cpp +++ b/core/audio_display.cpp @@ -71,6 +71,7 @@ AudioDisplay::AudioDisplay(wxWindow *parent,VideoDisplay *display) diagUpdated = false; NeedCommit = false; loaded = false; + temporary = false; blockUpdate = false; dontReadTimes = false; holding = false; @@ -917,7 +918,26 @@ __int64 AudioDisplay::GetSampleAtMS(__int64 ms) { // Play void AudioDisplay::Play(int start,int end) { // Check provider - if (!provider) return; + if (!provider) { + // Load temporary provider from video + if (video->loaded) { + try { + // Get provider + provider = AudioProvider::GetAudioProvider(video->videoName, this, video->provider,0); + + // Get player + player = AudioPlayer::GetAudioPlayer(); + player->SetDisplayTimer(&UpdateTimer); + player->SetProvider(provider); + player->OpenStream(); + temporary = true; + } + catch (...) { + return; + } + } + if (!provider) return; + } // Set defaults __int64 num_samples = provider->GetNumSamples(); diff --git a/core/audio_display.h b/core/audio_display.h index ab8e9c692..cf05deaa0 100644 --- a/core/audio_display.h +++ b/core/audio_display.h @@ -119,6 +119,7 @@ public: bool NeedCommit; bool loaded; + bool temporary; int w,h; AudioBox *box; AudioKaraoke *karaoke; diff --git a/core/audio_provider.cpp b/core/audio_provider.cpp index d04b979b5..3b77a8e00 100644 --- a/core/audio_provider.cpp +++ b/core/audio_provider.cpp @@ -162,7 +162,7 @@ void AudioProvider::GetWaveForm(int *min,int *peak,__int64 start,int w,int h,int //////////////// // Get provider -AudioProvider *AudioProvider::GetAudioProvider(wxString filename, AudioDisplay *display, VideoProvider *vprovider) { +AudioProvider *AudioProvider::GetAudioProvider(wxString filename, AudioDisplay *display, VideoProvider *vprovider,int cache) { // Prepare provider AudioProvider *provider = NULL; @@ -181,15 +181,15 @@ AudioProvider *AudioProvider::GetAudioProvider(wxString filename, AudioDisplay * } // Change provider to RAM/HD cache if needed - int cacheMode = Options.AsInt(_T("Audio Cache")); - if (cacheMode) { + if (cache == -1) cache = Options.AsInt(_T("Audio Cache")); + if (cache) { AudioProvider *final = NULL; - + // Convert to RAM - if (cacheMode == 1) final = new RAMAudioProvider(provider); + if (cache == 1) final = new RAMAudioProvider(provider); // Convert to HD - if (cacheMode == 2) final = new HDAudioProvider(provider); + if (cache == 2) final = new HDAudioProvider(provider); // Reassign if (final) { diff --git a/core/audio_provider.h b/core/audio_provider.h index 7ae9683bd..2f6123253 100644 --- a/core/audio_provider.h +++ b/core/audio_provider.h @@ -76,5 +76,5 @@ public: int GetBytesPerSample(); void GetWaveForm(int *min,int *peak,__int64 start,int w,int h,int samples,float scale); - static AudioProvider *GetAudioProvider(wxString filename, AudioDisplay *display, VideoProvider *vprovider); + static AudioProvider *GetAudioProvider(wxString filename, AudioDisplay *display, VideoProvider *vprovider,int cache=-1); }; diff --git a/core/changelog.txt b/core/changelog.txt index 6523f905d..c1015c949 100644 --- a/core/changelog.txt +++ b/core/changelog.txt @@ -90,6 +90,7 @@ Please visit http://aegisub.net to download latest version - Implemented an Attached files list, where you can attach new fonts and graphics, extract them, or remove them from the script file. (AMZ) - The Font Collector can now collect fonts as script attachments. (AMZ) - Added recent menu to Video Timecodes. (AMZ) +- Playing in video mode will now play the audio as well even if it hasn't been previously loaded into audio mode (experimental). (AMZ) = 1.09 beta - 2006.01.16 =========================== diff --git a/core/video_display.cpp b/core/video_display.cpp index a67b47f97..23bb3c8b4 100644 --- a/core/video_display.cpp +++ b/core/video_display.cpp @@ -92,6 +92,7 @@ END_EVENT_TABLE() VideoDisplay::VideoDisplay(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) : wxWindow (parent, id, pos, size, style, name) { + audio = NULL; provider = NULL; curLine = NULL; backbuffer = NULL; @@ -202,9 +203,7 @@ void VideoDisplay::SetVideo(const wxString &filename) { length = provider->GetFrameCount(); fps = provider->GetFPS(); VFR_Input.SetCFR(fps); - - if (!VFR_Output.IsLoaded()) - VFR_Output.SetCFR(fps); + if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps); // Set range of slider ControlSlider->SetRange(0,length-1); @@ -236,6 +235,15 @@ void VideoDisplay::Reset() { int _w,_h; GetSize(&_w,&_h); SetSizeHints(_w,_h,_w,_h); + + // Remove temporary audio provider + if (audio && audio->temporary) { + delete audio->provider; + audio->provider = NULL; + delete audio->player; + audio->player = NULL; + audio->temporary = false; + } } void VideoDisplay::RefreshSubtitles() { @@ -821,8 +829,6 @@ void VideoDisplay::Play() { // Set variables IsPlaying = true; - StartTime = clock(); - PlayTime = StartTime; StartFrame = frame_n; EndFrame = -1; @@ -830,6 +836,8 @@ void VideoDisplay::Play() { audio->Play(VFR_Output.GetTimeAtFrame(StartFrame),-1); // Start timer + StartTime = clock(); + PlayTime = StartTime; Playback.SetOwner(this,VIDEO_PLAY_TIMER); Playback.Start(1); } @@ -842,6 +850,9 @@ void VideoDisplay::PlayLine() { AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); if (!curline) return; + // Start playing audio + audio->Play(curline->Start.GetMS(),curline->End.GetMS()); + // Set variables IsPlaying = true; StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true); @@ -855,9 +866,6 @@ void VideoDisplay::PlayLine() { StartTime = clock(); PlayTime = StartTime; - // Start playing audio - audio->Play(curline->Start.GetMS(),curline->End.GetMS()); - // Start timer Playback.SetOwner(this,VIDEO_PLAY_TIMER); Playback.Start(1); @@ -902,6 +910,9 @@ void VideoDisplay::OnPlayTimer(wxTimerEvent &event) { return; } + // Next frame is before or over 2 frames ahead, so force audio resync + if (nextFrame < frame_n || nextFrame > frame_n + 2) audio->player->SetCurrentPosition(audio->GetSampleAtMS(VFR_Output.GetTimeAtFrame(nextFrame))); + // Jump to next frame PlayNextFrame = nextFrame; JumpToFrame(nextFrame); @@ -910,7 +921,10 @@ void VideoDisplay::OnPlayTimer(wxTimerEvent &event) { if (nextFrame % 10 == 0) { __int64 audPos = audio->GetSampleAtMS(VFR_Output.GetTimeAtFrame(nextFrame)); __int64 curPos = audio->player->GetCurrentPosition(); - if (abs(int(audPos-curPos)) > audio->provider->GetSampleRate() / 10) audio->player->SetCurrentPosition(audPos); + int delta = int(audPos-curPos); + if (delta < 0) delta = -delta; + int maxDelta = audio->provider->GetSampleRate(); + if (delta > maxDelta) audio->player->SetCurrentPosition(audPos); } }