Skip to content

Commit

Permalink
it now may open elfenLied.mid correctly!
Browse files Browse the repository at this point in the history
  • Loading branch information
klesun committed Sep 6, 2015
1 parent b817b1f commit 0025a2b
Show file tree
Hide file tree
Showing 22 changed files with 291 additions and 177 deletions.
Binary file modified shmidusic.jar
Binary file not shown.
22 changes: 11 additions & 11 deletions src/org/shmidusic/PianoLayoutPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.shmidusic.stuff.graphics.ImageStorage;
import org.apache.commons.math3.fraction.Fraction;
import org.shmidusic.stuff.tools.Fp;
import org.shmidusic.stuff.tools.INota;
import org.shmidusic.stuff.tools.INote;

import javax.swing.*;
import java.awt.*;
Expand Down Expand Up @@ -45,7 +45,7 @@ public PianoLayoutPanel(MainPanel mainPanel)
/** @return - tune of piano key pressed */
private int getPressed(MouseEvent e)
{
int tune = FIRST_TUNE + INota.fromIvory(e.getX() / IVORY_WIDTH);
int tune = FIRST_TUNE + INote.fromIvory(e.getX() / IVORY_WIDTH);
if (e.getY() < EBONY_LENGTH) {
tune -= e.getX() % IVORY_WIDTH < EBONY_WIDTH / 2 ? 1 : 0;
tune += e.getX() % IVORY_WIDTH > IVORY_WIDTH - EBONY_WIDTH / 2 ? 1 : 0;
Expand All @@ -57,7 +57,7 @@ private int getPressed(MouseEvent e)
@Override
public Dimension getPreferredSize()
{
return new Dimension(IVORY_WIDTH * INota.ivoryIndex(TUNE_COUNT), IVORY_LENGTH);
return new Dimension(IVORY_WIDTH * INote.ivoryIndex(TUNE_COUNT), IVORY_LENGTH);
};

@Override
Expand All @@ -69,9 +69,9 @@ public void paintComponent(Graphics g)
}

// draws such piano layout so it fitted to Rectangle r
private static void drawVanBascoLikePianoLayout(Graphics g, Set<INota> highlightEm)
private static void drawVanBascoLikePianoLayout(Graphics g, Set<INote> highlightEm)
{
Rectangle baseRect = new Rectangle(0, 0, IVORY_WIDTH * INota.ivoryIndex(TUNE_COUNT), IVORY_LENGTH);
Rectangle baseRect = new Rectangle(0, 0, IVORY_WIDTH * INote.ivoryIndex(TUNE_COUNT), IVORY_LENGTH);

// performance
g.setColor(Color.WHITE);
Expand All @@ -80,11 +80,11 @@ private static void drawVanBascoLikePianoLayout(Graphics g, Set<INota> highlight
g.setColor(new Color(225,225,225));
g.fillRect(baseRect.x, baseRect.y + baseRect.height - 3, baseRect.width, 3);

IntStream ivoryTunes = IntStream.range(FIRST_TUNE, FIRST_TUNE + TUNE_COUNT).filter(t -> !INota.isEbony(t));
IntStream ebonyTunes = IntStream.range(FIRST_TUNE, FIRST_TUNE + TUNE_COUNT).filter(INota::isEbony);
IntStream ivoryTunes = IntStream.range(FIRST_TUNE, FIRST_TUNE + TUNE_COUNT).filter(t -> !INote.isEbony(t));
IntStream ebonyTunes = IntStream.range(FIRST_TUNE, FIRST_TUNE + TUNE_COUNT).filter(INote::isEbony);

ivoryTunes.forEach(tune -> {
int ivoryIndex = INota.ivoryIndex(tune) - INota.ivoryIndex(FIRST_TUNE);
int ivoryIndex = INote.ivoryIndex(tune) - INote.ivoryIndex(FIRST_TUNE);
int pos = baseRect.x + ivoryIndex * IVORY_WIDTH;

Rectangle keyRect = new Rectangle(pos, baseRect.x, IVORY_WIDTH, baseRect.height);
Expand All @@ -100,7 +100,7 @@ private static void drawVanBascoLikePianoLayout(Graphics g, Set<INota> highlight
});

ebonyTunes.forEach(tune -> {
int ivoryNeighborIndex = INota.ivoryIndex(tune) - INota.ivoryIndex(FIRST_TUNE);
int ivoryNeighborIndex = INote.ivoryIndex(tune) - INote.ivoryIndex(FIRST_TUNE);
int pos = baseRect.x + ivoryNeighborIndex * IVORY_WIDTH - EBONY_WIDTH / 2;

Rectangle keyRect = new Rectangle(pos, baseRect.x, EBONY_WIDTH, EBONY_LENGTH);
Expand All @@ -118,9 +118,9 @@ private static void drawVanBascoLikePianoLayout(Graphics g, Set<INota> highlight
});
}

synchronized private Set<INota> getNotaSet()
synchronized private Set<INote> getNotaSet()
{
Set<INota> result = new TreeSet<>();
Set<INote> result = new TreeSet<>();

Staff staff = mainPanel.sheetContainer.getFocusedChild().staff;

Expand Down
82 changes: 71 additions & 11 deletions src/org/shmidusic/sheet_music/staff/Staff.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
import org.klesun_model.AbstractModel;
import org.shmidusic.sheet_music.staff.chord.Chord;
import org.shmidusic.sheet_music.staff.chord.Tact;
import org.shmidusic.sheet_music.staff.chord.nota.Nota;
import org.klesun_model.Explain;
import org.klesun_model.IModel;
import org.shmidusic.sheet_music.staff.staff_config.StaffConfig;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.shmidusic.MainPanel;
import org.shmidusic.stuff.graphics.Settings;

import java.util.Optional;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;


import org.shmidusic.stuff.tools.Fp;
import org.shmidusic.stuff.tools.INota;
import org.shmidusic.stuff.tools.INote;
import org.apache.commons.math3.fraction.Fraction;
import org.json.JSONArray;
import org.json.JSONException;
Expand All @@ -39,7 +39,8 @@ public enum aMode { insert, passive }

// TODO: MUAAAAH, USE FIELD CLASS MAZAFAKA AAAAAA!
private List<Chord> chordList = new ArrayList<>();
private List<Tact> tactList = new ArrayList<>();
/** @debug - public for debug - return private once done! */
public List<Tact> tactList = new ArrayList<>();
public int focusedIndex = -1;

public Staff()
Expand Down Expand Up @@ -90,34 +91,93 @@ private List<Tact> recalcTactList()
TactMeasurer measurer = new TactMeasurer(getConfig().getTactSize());

int i = 0;
Tact currentTact = new Tact(i++);
Tact currentTact = new Tact(i++, getConfig().getTactSize());
for (Chord chord : chordList) {
currentTact.accordList.add(chord);
currentTact.chordList.add(chord);
if (measurer.inject(chord)) {
currentTact.setPrecedingRest(measurer.sumFraction);
result.add(currentTact);
currentTact = new Tact(i++);
currentTact = new Tact(i++, getConfig().getTactSize());
}
}
if (currentTact.accordList.size() > 0) {
if (currentTact.chordList.size() > 0) {
result.add(currentTact);
}

return result;
}

public Explain<Tact> findTact(Chord chord)
public Optional<Tact> findTact(Chord chord)
{
// for now i'll use binary search, but this probably may be resolved with something efficientier
// like storing owner tact in each accord... nda...

int chordIdx = chordList.indexOf(chord);
Function<Tact, Integer> pred = t ->
t.accordList.get().contains(chord) ? 0 : chordIdx - chordList.indexOf(t.accordList.get(0));
t.chordList.get().contains(chord) ? 0 : chordIdx - chordList.indexOf(t.chordList.get(0));

return Fp.findBinary(tactList, pred);
}

public Optional<Fraction> findChordStart(Chord chord)
{
return findTact(chord).map(tact -> {
Fraction precedingChords = new LinkedList<Chord>(tact.chordList.get())
.subList(0, tact.chordList.indexOf(chord))
.stream().map(c -> c.getFraction())
.reduce(Fraction::add).orElse(new Fraction(0));

Fraction startFraction = getConfig().getTactSize().multiply(tact.tactNumber.get()).add(precedingChords);
if (!tact.getIsCorrect()) {
startFraction = startFraction.add(tact.getPrecedingRest());
}

return startFraction;
});
}

public Optional<Chord> findChord(Fraction start)
{
int tactNum = start.divide(getConfig().getTactSize()).intValue();
return getTact(tactNum).flatMap(tact -> {
Fraction chordPos = start.subtract(getConfig().getTactSize().multiply(tactNum));
return tact.findChord(chordPos);
});
}

public Optional<Chord> findClosestBefore(Fraction start)
{
if (chordList.size() == 0) {
return Optional.empty();
} else {
int tactNum = start.divide(getConfig().getTactSize()).intValue();
if (start.compareTo(getConfig().getTactSize().multiply(tactNum)) > 0) { // start is in the latter tact

Fraction chordPos = start.subtract(getConfig().getTactSize().multiply(tactNum));
return getTact(tactNum).flatMap(t -> t.findClosestBefore(chordPos));
} else {
Fraction chordPos = start.subtract(getConfig().getTactSize().multiply(tactNum - 1));
return getTact(tactNum - 1).flatMap(t -> t.findClosestBefore(chordPos));
}
}
}

private Optional<Tact> getTact(int index) {
return index >= 0 && index < tactList.size() ? Optional.of(tactList.get(index)) : Optional.empty();
}

public Optional<Chord> getChord(int index) {
if (index < 0) {
return chordList.size() + index >= 0
? Optional.of(chordList.get(chordList.size() + index))
: Optional.empty();
} else {
return chordList.size() > index
? Optional.of(chordList.get(index))
: Optional.empty();
}
}

// TODO: model, mazafaka!
@Override
public Staff reconstructFromJson(JSONObject jsObject) throws JSONException {
Expand Down Expand Up @@ -222,7 +282,7 @@ public TactMeasurer(Fraction tactSize) {

/** @returns true if chord finished the tact */
public Boolean inject(Chord chord) {
if (INota.isDotable(chord.getFraction())) {
if (INote.isDotable(chord.getFraction())) {
sumFraction = sumFraction.add(chord.getFraction());
} else {
sumFraction = new Fraction(sumFraction.doubleValue() + chord.getFraction().doubleValue());
Expand Down
6 changes: 3 additions & 3 deletions src/org/shmidusic/sheet_music/staff/StaffPainter.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.apache.commons.math3.fraction.Fraction;
import org.shmidusic.sheet_music.staff.staff_config.StaffConfigComponent;
import org.shmidusic.stuff.graphics.ImageStorage;
import org.shmidusic.stuff.tools.INota;
import org.shmidusic.stuff.tools.INote;

import java.awt.*;

Expand Down Expand Up @@ -70,11 +70,11 @@ private void drawStaffLines(int y)
StaffComponent comp = (StaffComponent)context;
Staff s = comp.staff;

int tune = INota.nextIvoryTune(INota.nextIvoryTune(Nota.FA + 12 * 2));
int tune = INote.nextIvoryTune(INote.nextIvoryTune(Nota.FA + 12 * 2));

// normal Nota height lines
for (int j = 0; j < 11; ++j) {
tune = INota.prevIvoryTune(INota.prevIvoryTune(tune));
tune = INote.prevIvoryTune(INote.prevIvoryTune(tune));
if (j == 5) continue;
int lineY = y + j * dy() * 2;
drawLine(-3 * dx(), lineY, comp.getWidth() - s.getMarginX() * 6, lineY, new Color(128,128,255));
Expand Down
31 changes: 20 additions & 11 deletions src/org/shmidusic/sheet_music/staff/chord/Chord.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.klesun_model.AbstractModel;
import org.klesun_model.field.Arr;
import org.klesun_model.field.Field;
import org.shmidusic.stuff.tools.INota;
import org.shmidusic.stuff.tools.INote;
import org.apache.commons.math3.fraction.Fraction;

import org.shmidusic.sheet_music.staff.chord.nota.Nota;
Expand Down Expand Up @@ -50,8 +50,7 @@ public int getShortestTime(int tempo) {
}

public Fraction getFraction() {
Nota nota = getShortest().orElse(null);
return nota != null ? nota.getRealLength() : new Fraction(0);
return getShortest().map(INote::getRealLength).orElse(new Fraction(0));
}

// field getters/setters
Expand All @@ -62,11 +61,20 @@ public Fraction getFraction() {
public Boolean getIsDiminendo() { return isDiminendo.get(); }
public void setIsDiminendo(Boolean value) { isDiminendo.set(value); }

public Chord setExplicitLength(Fraction length) {
addNewNota(0, 0).setLength(length);

removeRedundantPauseIfAny();
return this;
}

// event handles

public Nota addNewNota(INota source) {
public Nota addNewNota(INote source) {
Nota newNota = addNewNota(source.getTune(), source.getChannel()).setLength(source.getLength());
newNota.isTriplet.set(source.isTriplet());
removeRedundantPauseIfAny();

return newNota;
}

Expand All @@ -90,13 +98,14 @@ synchronized public void remove(Nota nota) {

public void removeRedundantPauseIfAny()
{
getShortest().ifPresent(n -> {
if (!n.isPause()) {
notaList.get().stream().filter(Nota::isPause)
.collect(Collectors.toList())
.forEach(this::remove);
}
});
getShortest().ifPresent(
n -> notaList.get().stream()
.filter(k -> k.getRealLength().equals(n.getRealLength()) && !k.isPause())
.findAny().ifPresent(
k -> notaList.get().stream().filter(Nota::isPause)
.collect(Collectors.toList())
.forEach(this::remove)
));
}

private Optional<Nota> getShortest() {
Expand Down
31 changes: 8 additions & 23 deletions src/org/shmidusic/sheet_music/staff/chord/ChordComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,37 +123,22 @@ public Dimension getPreferredSize() {
private KeySignature determineSignature()
{
KeySignature siga = getParentComponent().staff.getConfig().getSignature();
getParentComponent().staff.findTact(chord).whenSuccess(tact -> {
for (int i = 0; i < tact.accordList.indexOf(chord); ++i) {
siga.consume(tact.accordList.get(i));
}
}); // it may not be success when we delete chords
getParentComponent().staff.findTact(chord).ifPresent(tact -> {
for (int i = 0; i < tact.chordList.indexOf(chord); ++i) {
siga.consume(tact.chordList.get(i));
}
}); // it may not be success when we delete chords

return siga;
}

/** @return timestamp in seconds */
public Double determineStartTimestamp()
{
StaffConfig config = getParentComponent().staff.getConfig();
Explain<Tact> opt = getParentComponent().staff.findTact(chord);

if (opt.isSuccess()) {
Tact tact = opt.getData();
Fraction precedingChords = new LinkedList<>(tact.accordList.get())
.subList(0, tact.accordList.indexOf(chord))
.stream().map(c -> c.getFraction())
.reduce(Fraction::add).orElse(new Fraction(0));

Fraction startFraction = config.getTactSize().multiply(tact.tactNumber.get()).add(precedingChords);
if (!tact.getIsCorrect()) {
startFraction = startFraction.add(tact.getPrecedingRest());
}
StaffConfig config = getParentComponent().staff.getConfig();
Fraction chordStart = getParentComponent().staff.findChordStart(chord).orElse(new Fraction(-100));

return Nota.getTimeMilliseconds(startFraction, config.getTempo()) / 1000.0;
} else {
return - 100.0;
}
return Nota.getTimeMilliseconds(chordStart, config.getTempo()) / 1000.0;
}

// ========================
Expand Down
Loading

0 comments on commit 0025a2b

Please sign in to comment.