-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
67,508 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# als | ||
|
||
## Piste audio original | ||
|
||
XPath relatif | ||
à `/Ableton/LiveSet/Tracks/AudioTrack[1]/DeviceChain/MainSequencer/Sample/ArrangerAutomation/Events/AudioClip`. | ||
|
||
| XPath | Description | Exemple | | ||
|-----------------------------------------|--------------------------------------------------------|---------------------------------------------------------| | ||
| `CurrentStart/@Value` | Début du clip dans l'arrangeur (en BeatTime) | 0 | | ||
| `CurrentEnd/@Value` | Fin du clip dans l'arrangeur (en BeatTime) | 378.36283820346318 | | ||
| `Loop/HiddenLoopStart/@Value` | Début du sample dans le clip (en BeatTime) | -1.1762159715284715 | | ||
| `Loop/HiddenLoopEnd/@Value` | Fin du sample dans le clip (en BeatTime) | 378.36283820346318 | | ||
| `Name/@Value` | Nom du clip (par défaut, nom du sample sans extension) | DIDAFTA PETIT PAPILLON Master Web 24bit 48Khz_02-01 | | ||
| `ColorIndex/@Value` | Couleur du clip | 20 | | ||
| `SampleRef/FileRef/RelativePath` | Sous dossiers du sample relatifs au projet | Samples + lalicornerouge[...] + DIDAFTA - ALBUM | | ||
| `SampleRef/FileRef/SearchHint/PathHint` | Plus complet que `RelativePath` | Musique + Groupes + Didaf'ta + Samples + [...] | | ||
| `SampleRef/FileRef/Name` | Nom du sample avec extension | DIDAFTA PETIT PAPILLON Master Web 24bit 48Khz_02-01.wav | | ||
| `SampleRef/DefaultDuration/@Value` | Durée en échantillons du sample | 9984000 | | ||
| `SampleRef/DefaultSampleRate/@Value` | Fréquence d'échantillonnage du sample | 48000 | | ||
|
||
On peut déduire la durée du sample en secondes = DefaultDuration / DefaultSampleRate | ||
|
||
## Piste structure | ||
|
||
XPath relatif | ||
à `/Ableton/LiveSet/Tracks/MidiTrack[1]/DeviceChain/MainSequencer/ClipTimeable/ArrangerAutomation/Events/MidiClip`. | ||
|
||
| XPath | Description | Exemple | | ||
|-----------------------|--------------------------------------------------------|-----------------| | ||
| `CurrentStart/@Value` | Début du clip dans l'arrangeur (en BeatTime) | 0 | | ||
| `CurrentEnd/@Value` | Fin du clip dans l'arrangeur (en BeatTime) | 48 | | ||
| `Name/@Value` | Nom du clip (par défaut, nom du sample sans extension) | Partie bombarde | | ||
| `ColorIndex/@Value` | Couleur du clip | 22 | | ||
|
||
# Voir aussi | ||
|
||
- https://github.com/Bludwarf/als-player |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import {AlsImporter} from "./als-importer"; | ||
import {getKarmaFile} from "../test/test-utils"; | ||
import {StructureExtractorFromAls} from "./structure-extractor-from-als"; | ||
import {Time} from "../time"; | ||
|
||
describe('AlsExtractor', () => { | ||
|
||
const createExtractorFor = async (filePath: string): Promise<StructureExtractorFromAls> => { | ||
const alsImporter = new AlsImporter(); | ||
const blob = await getKarmaFile(filePath) | ||
const alsProject = await alsImporter.loadUnzipped(blob) | ||
return new StructureExtractorFromAls(alsProject) | ||
} | ||
|
||
it('should get sample duration from Petit papillon', async () => { | ||
const alsImporter = new AlsImporter(); | ||
const filePath = 'src/assets/als/Petit papillon.als.xml'; | ||
const extractor = await createExtractorFor(filePath) | ||
expect(extractor.sampleDuration.toSeconds()).toBe(Time.fromValue(208).toSeconds()) | ||
}); | ||
|
||
it('should get JSON structure from Petit papillon', async () => { | ||
const alsImporter = new AlsImporter(); | ||
const filePath = 'src/assets/als/Petit papillon.als.xml'; | ||
const extractor = await createExtractorFor(filePath) | ||
const jsonStructure = extractor.structureObject | ||
console.log(JSON.stringify(jsonStructure)) | ||
expect(jsonStructure).toBeTruthy() | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {AlsImporter} from "./als-importer"; | ||
import {getKarmaFile} from "../test/test-utils"; | ||
|
||
describe('AlsImporter', () => { | ||
|
||
// it('should load Petit papillon.als', (done) => { | ||
// const alsImporter = new AlsImporter(); | ||
// | ||
// | ||
// // Source : https://stackoverflow.com/a/57331494/1655155 | ||
// const filePath = 'src/assets/als/Petit papillon.als'; | ||
// const request: XMLHttpRequest = createRequest(filePath ); | ||
// | ||
// request.onload = async r => { | ||
// let blob = new Blob([request.response]); | ||
// const url = URL.createObjectURL(blob); | ||
// await alsImporter.load(blob) | ||
// // expect(data).toBe('expected data'); | ||
// done(); | ||
// }; | ||
// | ||
// // trigger | ||
// request.send(null); | ||
// }); | ||
|
||
it('should load Petit papillon.als.xml', async (done) => { | ||
const alsImporter = new AlsImporter(); | ||
const filePath = 'src/assets/als/Petit papillon.als.xml'; | ||
const blob = await getKarmaFile(filePath) | ||
const alsProject = await alsImporter.loadUnzipped(blob) | ||
expect(alsProject).toBeTruthy(); | ||
done(); | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// import * as zip from "@zip.js/zip.js"; | ||
// import {ZipReaderConstructorOptions} from "@zip.js/zip.js"; | ||
// const abletonParser = require('ableton-parser'); | ||
|
||
// const unzip = require('unzip-js') | ||
|
||
import {AlsProject} from "./v10/als-project"; | ||
|
||
declare function require(name:string): any; // source : https://stackoverflow.com/a/12742371/1655155 | ||
|
||
var convert = require('xml-js') | ||
|
||
// TODO trouver un utilitaire pour dézipper côté client | ||
|
||
export class AlsImporter { | ||
|
||
// async load(file: Blob): Promise<void> { | ||
// console.log(file.size) | ||
// const options: ZipReaderConstructorOptions = {} as ZipReaderConstructorOptions | ||
// | ||
// // Source : https://github.com/gildas-lormeau/zip.js/blob/gh-pages/demos/demo-read-file.js | ||
// | ||
// const blobReader = new zip.BlobReader(file); | ||
// console.log('blobReader', blobReader) | ||
// | ||
// const zipReader = new zip.ZipReader(blobReader); | ||
// console.log('zipReader', zipReader) | ||
// | ||
// const entries = await zipReader.getEntries(options) | ||
// console.log(entries) | ||
// } | ||
|
||
// load(file: Blob) { | ||
// unzip(file, function (err: any, zipFile: any) { | ||
// if (err) { | ||
// return console.error(err) | ||
// } | ||
// | ||
// zipFile.readEntries(function (err: any, entries: any) { | ||
// if (err) { | ||
// return console.error(err) | ||
// } | ||
// | ||
// entries.forEach(function (entry: any) { | ||
// zipFile.readEntryData(entry, false, function (err: any, readStream: any) { | ||
// if (err) { | ||
// return console.error(err) | ||
// } | ||
// | ||
// readStream.on('data', function (chunk: any) { | ||
// }) | ||
// readStream.on('error', function (err: any) { | ||
// }) | ||
// readStream.on('end', function () { | ||
// }) | ||
// }) | ||
// }) | ||
// }) | ||
// }) | ||
// } | ||
|
||
async loadUnzipped(xmlFile: Blob) { | ||
// TODO utiliser plutôt des stream | ||
const xmlContent = await xmlFile.text() | ||
const parsedXml = convert.xml2json(xmlContent, { | ||
compact: true, | ||
}) | ||
return new AlsProject(JSON.parse(parsedXml)) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {AlsProject} from "./v10/als-project"; | ||
import {AudioTrack} from "./v10/audio-track"; | ||
import {Time} from "../time"; | ||
|
||
export class StructureExtractorFromAls { | ||
constructor(private readonly alsProject: AlsProject) { | ||
|
||
} | ||
|
||
get originalAudioTrack(): AudioTrack { | ||
return this.alsProject.audioTracks[0] | ||
} | ||
|
||
get sampleDuration(): Time { | ||
const duration = this.originalAudioTrack.audioClips[0].duration | ||
const sampleRate = this.originalAudioTrack.audioClips[0].sampleRate | ||
return Time.fromValue(duration / sampleRate) | ||
} | ||
|
||
get structureObject(): StructureObject { | ||
return { | ||
sampleDuration: this.sampleDuration.toSeconds(), | ||
} | ||
} | ||
|
||
} | ||
|
||
export interface StructureObject { | ||
sampleDuration: number | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import {AudioTrack} from "./audio-track"; | ||
|
||
export class AlsProject { | ||
constructor(private readonly parsedXml: any) { | ||
|
||
} | ||
get audioTracks(): AudioTrack[] { | ||
return this.parsedXml.Ableton.LiveSet.Tracks.AudioTrack.map((audioTrack: any) => new AudioTrack(audioTrack)) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export class AudioClip { | ||
|
||
constructor(private readonly xmlAudioClip: any) { | ||
|
||
} | ||
|
||
get duration(): number { | ||
return +this.xmlAudioClip.SampleRef.DefaultDuration._attributes.Value | ||
} | ||
|
||
get sampleRate(): number { | ||
return +this.xmlAudioClip.SampleRef.DefaultSampleRate._attributes.Value | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import {AudioClip} from "./audio-clip"; | ||
|
||
export class AudioTrack { | ||
constructor(private readonly xmlObject: any) { | ||
} | ||
|
||
get audioClips(): AudioClip[] { | ||
const xmlAudioClip = this.xmlObject.DeviceChain.MainSequencer.Sample.ArrangerAutomation.Events.AudioClip as any; | ||
return [new AudioClip(xmlAudioClip)] | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<input type="file" accept=".xml" (change)="uploadFile($event)"/> | ||
<textarea #textarea></textarea> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { ConvertComponent } from './convert.component'; | ||
|
||
describe('ConvertComponent', () => { | ||
let component: ConvertComponent; | ||
let fixture: ComponentFixture<ConvertComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [ConvertComponent] | ||
}) | ||
.compileComponents(); | ||
|
||
fixture = TestBed.createComponent(ConvertComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import {Component, ElementRef, ViewChild} from '@angular/core'; | ||
import convert from "xml-js"; | ||
|
||
@Component({ | ||
selector: 'app-convert', | ||
standalone: true, | ||
imports: [], | ||
templateUrl: './convert.component.html', | ||
styleUrl: './convert.component.scss' | ||
}) | ||
export class ConvertComponent { | ||
|
||
@ViewChild('textarea') | ||
textArea?: ElementRef<HTMLTextAreaElement> | ||
|
||
async uploadFile(event: Event): Promise<void> { | ||
|
||
if (!this.textArea) { | ||
throw new Error('No textArea') | ||
} | ||
|
||
const element = event.currentTarget as HTMLInputElement; | ||
let fileList: FileList | null = element.files; | ||
if (!fileList?.length) { | ||
return; | ||
} | ||
|
||
const xmlFile = fileList[0] | ||
const xmlContent = await xmlFile.text() | ||
const xmlObject = convert.xml2json(xmlContent, { | ||
compact: true, | ||
}) | ||
|
||
this.textArea.nativeElement.value = xmlObject | ||
} | ||
} |
Oops, something went wrong.