Skip to content

Commit

Permalink
iOS: WaveFormView/WaveFormCacheManager: Fixed bug where the wave form…
Browse files Browse the repository at this point in the history
… would not be updated right after generating the peak file.

Related to issue #405.
  • Loading branch information
ycastonguay committed Apr 17, 2013
1 parent 5965d2e commit 0c56079
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 45 deletions.
17 changes: 16 additions & 1 deletion MPfm/MPfm.iOS/Classes/Controls/MPfmWaveFormView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,34 +147,47 @@ public MPfmWaveFormView(RectangleF frame)

private void Initialize()
{
Console.WriteLine("MPfmWaveFormView - Initialize");
this.BackgroundColor = UIColor.Black;
DisplayType = WaveFormDisplayType.Stereo;
_waveFormCacheManager = Bootstrapper.GetContainer().Resolve<WaveFormCacheManager>();
_waveFormCacheManager.GeneratePeakFileBegunEvent += HandleGeneratePeakFileBegunEvent;
_waveFormCacheManager.GeneratePeakFileProgressEvent += HandleGeneratePeakFileProgressEvent;
_waveFormCacheManager.GeneratePeakFileEndedEvent += HandleGeneratePeakFileEndedEvent;
_waveFormCacheManager.LoadedPeakFileSuccessfullyEvent += HandleLoadedPeakFileSuccessfullyEvent;
_waveFormCacheManager.GenerateWaveFormBitmapBegunEvent += HandleGenerateWaveFormBegunEvent;
_waveFormCacheManager.GenerateWaveFormBitmapEndedEvent += HandleGenerateWaveFormEndedEvent;
}

private void HandleGeneratePeakFileBegunEvent(object sender, GeneratePeakFileEventArgs e)
{
InvokeOnMainThread(() => {
Console.WriteLine("MPfmWaveFormView - HandleGeneratePeakFileBegunEvent");
RefreshStatus("Generating wave form (0% done)");
});
}

private void HandleGeneratePeakFileProgressEvent(object sender, GeneratePeakFileEventArgs e)
{
InvokeOnMainThread(() => {
Console.WriteLine("MPfmWaveFormView - HandleGeneratePeakFileProgressEvent (" + e.PercentageDone.ToString("0") + "% done)");
RefreshStatus("Generating wave form (" + e.PercentageDone.ToString("0") + "% done)");
});
}

private void HandleGeneratePeakFileEndedEvent(object sender, GeneratePeakFileEventArgs e)
{
InvokeOnMainThread(() => {
_waveFormCacheManager.RequestBitmap(e.AudioFilePath, WaveFormDisplayType.Stereo, Bounds, 1);
Console.WriteLine("MPfmWaveFormView - HandleGeneratePeakFileEndedEvent");
_waveFormCacheManager.LoadPeakFile(new AudioFile(e.AudioFilePath));
});
}

private void HandleLoadedPeakFileSuccessfullyEvent(object sender, LoadPeakFileEventArgs e)
{
InvokeOnMainThread(() => {
Console.WriteLine("MPfmWaveFormView - HandleLoadedPeakFileSuccessfullyEvent");
_waveFormCacheManager.RequestBitmap(e.AudioFile.FilePath, WaveFormDisplayType.Stereo, Bounds, 1);
});
}

Expand Down Expand Up @@ -207,6 +220,8 @@ void HandleOnPeakFileProcessDone(PeakFileDoneData data)

public void FlushCache()
{
_waveFormCacheManager.FlushCache();

if(_imageCache != null)
{
_imageCache.Dispose();
Expand Down
32 changes: 32 additions & 0 deletions MPfm/MPfm.iOS/Classes/Managers/Events/LoadPeakFileEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright © 2011-2013 Yanick Castonguay
//
// This file is part of MPfm.
//
// MPfm is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MPfm is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MPfm. If not, see <http://www.gnu.org/licenses/>.

using System;
using MPfm.Sound.AudioFiles;

namespace MPfm.iOS.Managers.Events
{
public class LoadPeakFileEventArgs : EventArgs
{
public AudioFile AudioFile { get; set; }

public LoadPeakFileEventArgs()
: base()
{
}
}
}
87 changes: 43 additions & 44 deletions MPfm/MPfm.iOS/Classes/Managers/WaveFormCacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MPfm.iOS.Classes.Controls;
using MPfm.iOS.Managers.Events;
using MPfm.iOS.Helpers;
using MPfm.iOS.Classes.Objects;
using MPfm.iOS.Helpers;
using MPfm.iOS.Managers.Events;

namespace MPfm.iOS.Managers
{
Expand All @@ -47,12 +47,14 @@ public class WaveFormCacheManager
private CGColor _colorGradient2 = GlobalTheme.BackgroundColor.CGColor;
private float _padding = 0;

public delegate void LoadPeakFileEventHandler(object sender, LoadPeakFileEventArgs e);
public delegate void GeneratePeakFileEventHandler(object sender, GeneratePeakFileEventArgs e);
public delegate void GenerateWaveFormEventHandler(object sender, GenerateWaveFormEventArgs e);

public event GeneratePeakFileEventHandler GeneratePeakFileBegunEvent;
public event GeneratePeakFileEventHandler GeneratePeakFileProgressEvent;
public event GeneratePeakFileEventHandler GeneratePeakFileEndedEvent;
public event LoadPeakFileEventHandler LoadedPeakFileSuccessfullyEvent;
public event GenerateWaveFormEventHandler GenerateWaveFormBitmapBegunEvent;
public event GenerateWaveFormEventHandler GenerateWaveFormBitmapEndedEvent;

Expand Down Expand Up @@ -82,6 +84,12 @@ protected virtual void OnGeneratePeakFileEnded(GeneratePeakFileEventArgs e)
GeneratePeakFileEndedEvent(this, e);
}

protected virtual void OnLoadedPeakFileSuccessfully(LoadPeakFileEventArgs e)
{
if(LoadedPeakFileSuccessfullyEvent != null)
LoadedPeakFileSuccessfullyEvent(this, e);
}

protected virtual void OnGenerateWaveFormBitmapBegun(GenerateWaveFormEventArgs e)
{
if(GenerateWaveFormBitmapBegunEvent != null)
Expand All @@ -96,11 +104,13 @@ protected virtual void OnGenerateWaveFormBitmapEnded(GenerateWaveFormEventArgs e

void HandleOnPeakFileProcessStarted(PeakFileStartedData data)
{
Console.WriteLine("WaveFormCacheManager - HandleOnPeakFileProcessStarted");
OnGeneratePeakFileBegun(new GeneratePeakFileEventArgs());
}

void HandleOnPeakFileProcessData(PeakFileProgressData data)
{
Console.WriteLine("WaveFormCacheManager - HandleOnPeakFileProcessData");
OnGeneratePeakFileProgress(new GeneratePeakFileEventArgs(){
AudioFilePath = data.AudioFilePath,
PercentageDone = data.PercentageDone
Expand All @@ -109,42 +119,22 @@ void HandleOnPeakFileProcessData(PeakFileProgressData data)

void HandleOnPeakFileProcessDone(PeakFileDoneData data)
{
Console.WriteLine("WaveFormCacheManager - HandleOnPeakFileProcessDone");

OnGeneratePeakFileEnded(new GeneratePeakFileEventArgs(){
AudioFilePath = data.AudioFilePath,
PercentageDone = 100
});
}

// Flow:
// LoadPeakFile(filePath)
// Control displays "Loading peak file"
// Peak file doesn't exist
// Sending GeneratingPeakFile event
// Generating peak file
// Peak file exists
// Loads peak file
// Peak file is loaded.

// Flow:
// Control requests bitmap at 100% zoom
// Generating wave form.
// Is wave form in cache?
// Return bitmap
// No, generating bitmap
// Tell control the bitmap has been loaded

// Flow:
// User changes the zoom level on the control
// Same as before but specify a different zoom.
// Thus the bitmap always returns to the control by an event.
public void FlushCache()
{
_waveDataCache = null;
_bitmapCache = null;
}

public void LoadPeakFile(AudioFile audioFile)
{
// Indicate peak file loading
bool isLoading = true;
string status = "Loading peak file...";
//SetNeedsDisplay();

// Check if another peak file is already loading
Console.WriteLine("WaveFormCacheManager - LoadPeakFile audioFile: " + audioFile.FilePath);
if (_peakFileService.IsLoading)
Expand All @@ -157,7 +147,7 @@ public void LoadPeakFile(AudioFile audioFile)
try
{
Console.WriteLine("WaveFormCacheManager - Creating folder " + peakFileFolder + "...");
DirectoryInfo directoryInfo = Directory.CreateDirectory(peakFileFolder);
Directory.CreateDirectory(peakFileFolder);
}
catch(Exception ex)
{
Expand Down Expand Up @@ -202,17 +192,16 @@ public void LoadPeakFile(AudioFile audioFile)
List<WaveDataMinMax> data = (List<WaveDataMinMax>)t.Result;
if (data == null)
{
Console.WriteLine("WaveFormCacheManager - Could not load peak file succesfully.");
Console.WriteLine("WaveFormCacheManager - Could not load a peak file from disk (i.e. generating a new peak file).");
return;
}
Console.WriteLine("WaveFormCacheManager - Adding wave data to cache...");
if(!_waveDataCache.ContainsKey(audioFile.FilePath))
_waveDataCache.Add(audioFile.FilePath, data);
OnGeneratePeakFileEnded(new GeneratePeakFileEventArgs(){
AudioFilePath = audioFile.FilePath,
PercentageDone = 100
OnLoadedPeakFileSuccessfully(new LoadPeakFileEventArgs(){
AudioFile = audioFile
});
}, TaskScheduler.FromCurrentSynchronizationContext());
Expand Down Expand Up @@ -242,18 +231,27 @@ public void RequestBitmap(string audioFilePath, WaveFormDisplayType displayType,
boundsWaveForm = new RectangleF(0, 0, widthAvailable - (_padding * 2), heightAvailable - (_padding * 2));

Task<UIImage>.Factory.StartNew(() => {
CGContext context;
try
{
Console.WriteLine("WaveFormCacheManager - Creating image cache...");
UIGraphics.BeginImageContextWithOptions(bounds.Size, false, 0);
var context = UIGraphics.GetCurrentContext();
context = UIGraphics.GetCurrentContext();
if (context == null)
{
// Error
Console.WriteLine("Error initializing image cache!");
Console.WriteLine("Error initializing image cache context!");
return null;
}
}
catch(Exception ex)
{
Console.WriteLine("Error while creating image cache context: " + ex.Message);
return null;
}
try
{
// Draw gradient background
CoreGraphicsHelper.FillGradient(context, bounds, _colorGradient1, _colorGradient2);
Expand Down Expand Up @@ -307,7 +305,7 @@ public void RequestBitmap(string audioFilePath, WaveFormDisplayType displayType,
nHistoryItemsPerLine = 1;
}
Console.WriteLine("WaveFormView - historyItemsPerLine: " + nHistoryItemsPerLine.ToString());
//Console.WriteLine("WaveFormView - historyItemsPerLine: " + nHistoryItemsPerLine.ToString());
context.SetStrokeColor(GlobalTheme.WaveFormColor.CGColor);
context.SetLineWidth(0.5f);
Expand Down Expand Up @@ -452,17 +450,18 @@ public void RequestBitmap(string audioFilePath, WaveFormDisplayType displayType,
if (historyIndex < historyCount - 1)
historyIndex += nHistoryItemsPerLine;
}
// Get image from context
imageCache = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return imageCache;
}
catch(Exception ex)
{
Console.WriteLine("Error while creating image cache: " + ex.Message);
}
return null;
finally
{
// Get image from context (at this point, we are sure the image context has been initialized properly)
imageCache = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
}
return imageCache;
}, TaskCreationOptions.LongRunning).ContinueWith(t => {
Console.WriteLine("WaveFormCacheManager - Created image successfully.");
OnGenerateWaveFormBitmapEnded(new GenerateWaveFormEventArgs(){
Expand Down
1 change: 1 addition & 0 deletions MPfm/MPfm.iOS/MPfm.iOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
<Compile Include="Classes\Controllers\EqualizerPresetDetailsViewController.designer.cs">
<DependentUpon>EqualizerPresetDetailsViewController.cs</DependentUpon>
</Compile>
<Compile Include="Classes\Managers\Events\LoadPeakFileEventArgs.cs" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="XIB\iPhone\SplashViewController_iPhone.xib" />
Expand Down

0 comments on commit 0c56079

Please sign in to comment.