From 108064ae2e51ca43519524526797cfb569472557 Mon Sep 17 00:00:00 2001 From: Lucas Veiga Date: Tue, 27 Jun 2023 08:07:06 -0300 Subject: [PATCH 1/5] Update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d689b62..bf65026 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,21 @@ -

drawing

+

logo

# Hitsound Copier +preview Cross platfrom hitsound copier for osu! standard beatmaps (for now) written in TypeScript, using osu!lazer's hitsound logic as base. It was done so we could have a hitsound copier solution that was friendly to run on Linux without the need of third party tools. -## Tools +
+
+ +### Built with - Tauri - TypeScript - [osu-parsers](https://github.com/kionell/osu-parsers) +
+ ## Running If you wish to run the project on your local machine, follow the instructions below: From 421090a8063bd5839889b7f68f189928b6c2fad2 Mon Sep 17 00:00:00 2001 From: Lucas Veiga Date: Tue, 27 Jun 2023 08:07:22 -0300 Subject: [PATCH 2/5] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index bf65026..361f555 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ preview Cross platfrom hitsound copier for osu! standard beatmaps (for now) written in TypeScript, using osu!lazer's hitsound logic as base. It was done so we could have a hitsound copier solution that was friendly to run on Linux without the need of third party tools. -

### Built with From 8500b32ad2c42c47ac8f26d58de1c6840f0f9fc5 Mon Sep 17 00:00:00 2001 From: FelipeSSDev <13539403+FelipeSSDev@users.noreply.github.com> Date: Tue, 27 Jun 2023 08:36:51 -0300 Subject: [PATCH 3/5] refactor: update utils file --- .../service/copy-slider-hitsounds.ts | 5 +- src/copier/utils.ts | 79 +++++++++++-------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/copier/hitsounds/service/copy-slider-hitsounds.ts b/src/copier/hitsounds/service/copy-slider-hitsounds.ts index acb93e4..c54862c 100644 --- a/src/copier/hitsounds/service/copy-slider-hitsounds.ts +++ b/src/copier/hitsounds/service/copy-slider-hitsounds.ts @@ -1,11 +1,12 @@ -import { HitSample, HitSound } from "osu-classes"; +import type { HitsoundableTimeLineObject, Options } from "src/copier/types"; + import { SliderTail, type Slider, StandardBeatmap, SliderTick, } from "osu-standard-stable"; -import type { HitsoundableTimeLineObject, Options } from "src/copier/types"; +import { HitSample, HitSound } from "osu-classes"; import { findNearestHitObject } from "../../utils"; export type CopySliderHitsoundsParams = { diff --git a/src/copier/utils.ts b/src/copier/utils.ts index 8d75878..9eb8390 100644 --- a/src/copier/utils.ts +++ b/src/copier/utils.ts @@ -1,4 +1,8 @@ -import { HitSound, HitSample, SampleSet } from "osu-classes"; +import type { + FindNearestHitObjectParams, + HitsoundableTimeLineObject, +} from "./types"; + import { Circle, Slider, @@ -7,10 +11,7 @@ import { Spinner, type StandardBeatmap, } from "osu-standard-stable"; -import type { - FindNearestHitObjectParams, - HitsoundableTimeLineObject, -} from "./types"; +import { HitSound, HitSample, SampleSet } from "osu-classes"; export const calculateSampleBitwise = (samples: HitSample[]) => { let bitwise = 0; @@ -21,11 +22,28 @@ export const calculateSampleBitwise = (samples: HitSample[]) => { return bitwise; }; +const resetUndefinedHitsoundSamples = (samples: HitSample[]) => { + // This is a temporary workaround for a bug with the parser library that we are using, + // which causes undefined hitsounds to be considered Normal hitsounds + // when the hit object is a slider. + + if ( + samples.length == 1 && + samples[0].volume === 100 && + samples[0].sampleSet === SampleSet[SampleSet.Normal] + ) { + const newSample = new HitSample(); + + newSample.sampleSet = SampleSet[SampleSet.None]; + + samples = [newSample]; + } +}; + export const convertBeatmapToHitsoundableTimeLine = ( beatmap: StandardBeatmap ): HitsoundableTimeLineObject[] => { - let hitsoundableTimeLineObject = []; - console.log(beatmap.hitObjects); + const hitsoundableTimeLineObject: Array = []; beatmap.hitObjects.forEach((hitObject) => { if (hitObject instanceof Circle) { @@ -35,20 +53,12 @@ export const convertBeatmapToHitsoundableTimeLine = ( HitSound: hitObject.hitSound, clickable: true, }); - } else if (hitObject instanceof Slider) { - // This is a temporary workaround for a bug with the parser library that we are using, - // which causes undefined hitsounds to be considered Normal hitsounds - // when the hit object is a slider. - if ( - hitObject.samples.length == 1 && - hitObject.samples[0].volume === 100 && - hitObject.samples[0].sampleSet === SampleSet[SampleSet.Normal] - ) { - const newSample = new HitSample(); - newSample.sampleSet = SampleSet[SampleSet.None]; - - hitObject.samples = [newSample]; - } + + return; + } + + if (hitObject instanceof Slider) { + resetUndefinedHitsoundSamples(hitObject.samples); hitsoundableTimeLineObject.push({ startTime: hitObject.startTime, @@ -62,35 +72,34 @@ export const convertBeatmapToHitsoundableTimeLine = ( ); hitObject.nodeSamples.forEach((samples, key) => { - if ( - samples.length == 1 && - samples[0].volume === 100 && - samples[0].sampleSet === SampleSet[SampleSet.Normal] - ) { - const newSample = new HitSample(); - newSample.sampleSet = SampleSet[SampleSet.None]; + resetUndefinedHitsoundSamples(samples); - samples = [newSample]; - } + const keyStartTime = Math.round(nestedHitObjects[key].startTime); + const newHitSoundBitwise = calculateSampleBitwise(samples); hitsoundableTimeLineObject.push({ startTime: nestedHitObjects[key] instanceof SliderTail - ? Math.round(nestedHitObjects[key].startTime) + - hitObject.legacyLastTickOffset - : Math.round(nestedHitObjects[key].startTime), + ? keyStartTime + hitObject.legacyLastTickOffset + : keyStartTime, HitSample: samples, - HitSound: calculateSampleBitwise(samples), + HitSound: newHitSoundBitwise, clickable: true, }); }); - } else if (hitObject instanceof Spinner) { + + return; + } + + if (hitObject instanceof Spinner) { hitsoundableTimeLineObject.push({ startTime: hitObject.endTime, HitSample: hitObject.samples, HitSound: hitObject.hitSound, clickable: true, }); + + return; } }); From b7ad1acdf937e65590146f95f3da6e645ddeb239 Mon Sep 17 00:00:00 2001 From: maotovisk Date: Tue, 27 Jun 2023 08:42:02 -0300 Subject: [PATCH 4/5] refactor: rename volumes to control-points --- .../{volumes => control-points}/constants.ts | 0 .../services/copy.ts | 43 +++++++++++++------ .../services/is-muted.ts | 0 src/copier/copy-hitsounds.ts | 4 +- 4 files changed, 33 insertions(+), 14 deletions(-) rename src/copier/{volumes => control-points}/constants.ts (100%) rename src/copier/{volumes => control-points}/services/copy.ts (59%) rename src/copier/{volumes => control-points}/services/is-muted.ts (100%) diff --git a/src/copier/volumes/constants.ts b/src/copier/control-points/constants.ts similarity index 100% rename from src/copier/volumes/constants.ts rename to src/copier/control-points/constants.ts diff --git a/src/copier/volumes/services/copy.ts b/src/copier/control-points/services/copy.ts similarity index 59% rename from src/copier/volumes/services/copy.ts rename to src/copier/control-points/services/copy.ts index 20da627..8ebbcb0 100644 --- a/src/copier/volumes/services/copy.ts +++ b/src/copier/control-points/services/copy.ts @@ -1,47 +1,48 @@ import type { StandardBeatmap } from "osu-standard-stable"; import type { Options } from "src/copier/types"; -import { ControlPointType } from "osu-classes"; +import { ControlPointType, DifficultyPoint } from "osu-classes"; import { isMuted } from "./is-muted"; -type CopyVolumesParams = { +type CopySamplePointsParams = { originBeatmap: StandardBeatmap; destinationBeatmap: StandardBeatmap; options: Options; }; -export const copyVolumes = ({ +export const copySamplePoints = ({ originBeatmap, destinationBeatmap, options, -}: CopyVolumesParams) => { - const fromBeatmapSamplePoints = originBeatmap.controlPoints.samplePoints; - let toBeatmapSamplePoints = destinationBeatmap.controlPoints.samplePoints; +}: CopySamplePointsParams) => { + const originBeatmapSamplePoints = originBeatmap.controlPoints.samplePoints; + let destinationBeatmapSamplePoints = + destinationBeatmap.controlPoints.samplePoints; - fromBeatmapSamplePoints.forEach((samplePoint) => { + originBeatmapSamplePoints.forEach((samplePoint) => { if (!options.copySamplesetChanges) return; if (options.removeMuting && isMuted(samplePoint.volume)) return; - const fromBeatmapSamplePoint = + const destinationBeatmapSamplePoint = destinationBeatmap.controlPoints.samplePointAt(samplePoint.startTime); if (!options.copyVolumes) - samplePoint.volume = fromBeatmapSamplePoint.volume; + samplePoint.volume = destinationBeatmapSamplePoint.volume; destinationBeatmap.controlPoints .groupAt(samplePoint.startTime) - .remove(fromBeatmapSamplePoint); + .remove(destinationBeatmapSamplePoint); destinationBeatmap.controlPoints .groupAt(samplePoint.startTime) .add(samplePoint); }); - toBeatmapSamplePoints = [...fromBeatmapSamplePoints]; + destinationBeatmapSamplePoints = [...originBeatmapSamplePoints]; if (options.removeMuting) { - toBeatmapSamplePoints.forEach((samplePoint) => { + destinationBeatmapSamplePoints.forEach((samplePoint) => { if (isMuted(samplePoint.volume)) { destinationBeatmap.controlPoints .groupAt(samplePoint.startTime) @@ -50,6 +51,9 @@ export const copyVolumes = ({ }); } + // This is a hack to prevent that the destination is encoded with a 0 offset + // sample point that happens before the first timing point. + const firstDestinationControlPointGroup = destinationBeatmap.controlPoints.groups[0]; const secondDestionationControlPointGroup = @@ -79,5 +83,20 @@ export const copyVolumes = ({ .add(firstDestinationControlPointGroup.controlPoints[0]); destinationBeatmap.controlPoints.groups.shift(); + + const difficultyPointInSecondDestinationGroup = + secondDestionationControlPointGroup.controlPoints.find( + (controlPoint) => + controlPoint.pointType === ControlPointType.DifficultyPoint + ); + + if (!difficultyPointInSecondDestinationGroup) { + const newDifficultyPoint = new DifficultyPoint(); + newDifficultyPoint.sliderVelocity = 1; + + destinationBeatmap.controlPoints + .groupAt(secondDestionationControlPointGroup.startTime) + .add(newDifficultyPoint); + } } }; diff --git a/src/copier/volumes/services/is-muted.ts b/src/copier/control-points/services/is-muted.ts similarity index 100% rename from src/copier/volumes/services/is-muted.ts rename to src/copier/control-points/services/is-muted.ts diff --git a/src/copier/copy-hitsounds.ts b/src/copier/copy-hitsounds.ts index 68167cd..0214972 100644 --- a/src/copier/copy-hitsounds.ts +++ b/src/copier/copy-hitsounds.ts @@ -7,7 +7,7 @@ import { copySliderHitsounds, copySpinnerHitsounds, } from "./hitsounds/service"; -import { copyVolumes } from "./volumes/services/copy"; +import { copySamplePoints } from "./control-points/services/copy"; export const copyHitsounds = ( originBeatmap: StandardBeatmap, @@ -17,7 +17,7 @@ export const copyHitsounds = ( const hitsoundedBeatmap = destinationBeatmap; if (options.copySamplesetChanges || options.copyVolumes) { - copyVolumes({ + copySamplePoints({ originBeatmap, destinationBeatmap, options, From 7d2a3ad71f9476faf617a2e8ff0f050876ee2f88 Mon Sep 17 00:00:00 2001 From: maotovisk Date: Tue, 27 Jun 2023 09:24:22 -0300 Subject: [PATCH 5/5] 0.0.4 --- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 328027a..3ebe8f0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hitsound-copier", "private": true, - "version": "0.0.3", + "version": "0.0.4", "type": "module", "scripts": { "dev": "vite", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 40e37b8..75e2e4e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1116,7 +1116,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hitsound-copier" -version = "0.0.3" +version = "0.0.4" dependencies = [ "serde", "serde_json", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9773ff3..c1732cc 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hitsound-copier" -version = "0.0.3" +version = "0.0.4" description = "A Tauri App" authors = ["you"] license = "" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 71f227f..ffd53fd 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "hitsound-copier", - "version": "0.0.3" + "version": "0.0.4" }, "tauri": { "allowlist": {