Skip to content

Commit

Permalink
Implement playback cursor
Browse files Browse the repository at this point in the history
* Draw cursor frame.

* Add cursor bar.

* Implement FileSystemJcfLoader.LoadScoreNodes.

* Defined SongPage.MoveCursor.

* Use Xamarin Timer to move cursor.

* Implement FindBeat.
  • Loading branch information
JunielKatarn committed Nov 16, 2019
1 parent ca6ffab commit 31ad910
Show file tree
Hide file tree
Showing 7 changed files with 420 additions and 236 deletions.
26 changes: 24 additions & 2 deletions Core/Model/FileSystemJcfLoader.cs
Expand Up @@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;

using System.Text;
using Claunia.PropertyList;

namespace Jammit.Model
Expand Down Expand Up @@ -37,6 +37,8 @@ public JcfMedia LoadMedia(Model.SongInfo song)

LoadSections(result, songPath);

LoadScoreNodes(result, songPath);

return result;
}

Expand Down Expand Up @@ -163,11 +165,31 @@ private void LoadSections(JcfMedia media, string songPath)
}).ToList();
}

/// <summary>
/// Loads score nodes for each instrument track.
/// </summary>
/// <param name="media">Must already have InstrumentTracks set.</param>
/// <param name="songPath"></param>
private void LoadScoreNodes(JcfMedia media, string songPath)
{
using (var stream = File.OpenRead(Path.Combine(songPath, "nowline.nodes")))
{
//TODO: Emulate ScoreNodes.FromStream
var numTracks = stream.ReadInt32LE();
var temp = new byte[32];
for (var i = 0; i < numTracks; i++)
{
stream.Read(temp, 0, 32);
var title = Encoding.UTF8.GetString(temp, 0, 32);
title = title.Remove(title.IndexOf('\0'));

stream.Read(temp, 0, 32);
var type = Encoding.UTF8.GetString(temp, 0, 32);
type = type.Remove(type.IndexOf('\0'));

var nodes = BeatInfo.FromStream(stream);
var index = media.InstrumentTracks.FirstOrDefault(track => track.Title == title);
media.ScoreNodes[index] = new ScoreNodes(title, type, nodes);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Core/Model/JcfMedia.cs
Expand Up @@ -12,7 +12,7 @@ public JcfMedia(SongInfo song, string path)
Path = path;
InstrumentTracks = new List<NotatedTrackInfo>();
Scores = new List<ScoreInfo>();
ScoreNodes = new SortedList<PlayableTrackInfo, ScoreNodes>();
ScoreNodes = new SortedList<NotatedTrackInfo, ScoreNodes>();
}

public SongInfo Song { get; private set; }
Expand All @@ -34,7 +34,7 @@ public JcfMedia(SongInfo song, string path)
//TODO: Section
public IReadOnlyList<Section> Sections { get; set; }

public IDictionary<PlayableTrackInfo, ScoreNodes> ScoreNodes { get; private set; }
public IDictionary<NotatedTrackInfo, ScoreNodes> ScoreNodes { get; set; }

//TODO: WaveForm?

Expand Down
4 changes: 2 additions & 2 deletions Core/Model/ScoreNodes.cs
Expand Up @@ -11,7 +11,7 @@ public class ScoreNodes
public readonly string Type;
public readonly IReadOnlyList<BeatInfo> Nodes;

private ScoreNodes(string t, string y, IReadOnlyList<BeatInfo> nodes)
public ScoreNodes(string t, string y, IReadOnlyList<BeatInfo> nodes)
{
Title = t;
Type = y;
Expand Down Expand Up @@ -66,4 +66,4 @@ public static List<BeatInfo> FromStream(Stream s)
return list;
}
}
}
}
11 changes: 10 additions & 1 deletion Core/Model/TrackInfo.cs
Expand Up @@ -6,7 +6,7 @@

namespace Jammit.Model
{
public abstract class TrackInfo
public abstract class TrackInfo : IComparable<TrackInfo>
{
#region Properties

Expand All @@ -15,6 +15,15 @@ public abstract class TrackInfo
public Guid Identifier { get; set; }

#endregion

#region IComparable

public int CompareTo(TrackInfo other)
{
return Identifier.CompareTo(other.Identifier);
}

#endregion IComparable
}

/// <summary>
Expand Down
1 change: 0 additions & 1 deletion Forms/Views/AspectRatioContainer.cs
Expand Up @@ -14,7 +14,6 @@ public class AspectRatioContainer : ContentView
{
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
//return base.OnMeasure(widthConstraint, widthConstraint * AspectRatio);
return base.OnMeasure(widthConstraint, widthConstraint * AspectRatio);
}

Expand Down
44 changes: 36 additions & 8 deletions Forms/Views/SongPage.xaml
Expand Up @@ -21,8 +21,36 @@
HorizontalOptions="FillAndExpand" />
</StackLayout>

<ScrollView x:Name="ScoreLayout" BackgroundColor="LightGray" Padding="5,5,5,5">
<Image x:Name="ScoreImage" Aspect="AspectFit" HeightRequest="1024" />
<ScrollView x:Name="ScoreLayout" BackgroundColor="LightGray" Padding="0">
<RelativeLayout
HeightRequest="1024" MinimumHeightRequest="1024"
WidthRequest="724" MinimumWidthRequest="724"
VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Image x:Name="ScoreImage"
Aspect="AspectFit"
RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
/>

<Frame x:Name="CursorFrame"
BorderColor="Green"
BackgroundColor="Transparent"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=704}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=-352}">
</Frame>

<Frame x:Name="CursorBar"
BorderColor="Green"
BackgroundColor="Green"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=2}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=CursorFrame, Property=X, Constant=0}"
/>

<Label x:Name="BeatLabel"
TextColor="Blue"/>

</RelativeLayout>
</ScrollView>

<StackLayout x:Name="ControlsLayout" Orientation="Horizontal" HorizontalOptions="FillAndExpand" MinimumWidthRequest="100">
Expand Down Expand Up @@ -50,13 +78,13 @@
WidthRequest="10" />
<Image x:Name="TimelineImage" BackgroundColor="Black" VerticalOptions="FillAndExpand"/>
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
<Button x:Name="RepeatButton" Text="🔁" HorizontalOptions="Center" IsEnabled="False" />
<Button x:Name="StartButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="StartButton_Clicked" />
<Button x:Name="BackButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="BackButton_Clicked" />
<Button x:Name="PlayButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="PlayButton_Clicked" />
<Button x:Name="StopButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="StopButton_Clicked" />
<Button x:Name="RepeatButton" Text="🔁" HorizontalOptions="Center" IsEnabled="False" />
<Button x:Name="StartButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="StartButton_Clicked" />
<Button x:Name="BackButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="BackButton_Clicked" />
<Button x:Name="PlayButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="PlayButton_Clicked" />
<Button x:Name="StopButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="StopButton_Clicked" />
<Button x:Name="ForwardButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="ForwardButton_Clicked" />
<Button x:Name="EndButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="EndButton_Clicked" />
<Button x:Name="EndButton" Text="" HorizontalOptions="Center" FontSize="Small" Clicked="EndButton_Clicked" />
</StackLayout>
</StackLayout>
</StackLayout>
Expand Down

0 comments on commit 31ad910

Please sign in to comment.