WIP: StartOffset
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0ff2a59f9d4f5412792e5bba783f5c7a
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6b648c023f5e041a893c06ee0cd55839
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: deba7646359d5433aaecc6dbf9ec8e36
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cd9d756f436864f1c8b6a10dc273c708
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 207d0e7be17864f8996e1f3d2140d117
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a91860e6b5a5c47d9a8acaac55bebf40
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d8d6d1c358a444de6bf2863ee12c6a6e
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f805529718cf2490c81ddeeeca559a6c
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0546af815ebd141fabcda647c12e8ccf
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 2
|
||||||
|
sampleRateSetting: 2
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 0.13
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 921d30b7911b6459b82aeb4ce80bcae9
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 0
|
||||||
|
sampleRateSetting: 0
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 1
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4e8fa10885f1b4a81a45db662ff7af77
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ae19d4b3ec8be4679b092fbefc78f066
|
||||||
|
AudioImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 7
|
||||||
|
defaultSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
loadType: 2
|
||||||
|
sampleRateSetting: 2
|
||||||
|
sampleRateOverride: 44100
|
||||||
|
compressionFormat: 1
|
||||||
|
quality: 0.13
|
||||||
|
conversionMode: 0
|
||||||
|
preloadAudioData: 0
|
||||||
|
platformSettingOverrides: {}
|
||||||
|
forceToMono: 0
|
||||||
|
normalize: 1
|
||||||
|
loadInBackground: 0
|
||||||
|
ambisonic: 0
|
||||||
|
3D: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"major": 1,
|
||||||
|
"minor": 0,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"editor": "Haptic Editor",
|
||||||
|
"author": "Oliver",
|
||||||
|
"source": "au_coreplay_collect_handbag",
|
||||||
|
"project": "Magic_Sort",
|
||||||
|
"tags": [],
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"continuous": {
|
||||||
|
"envelopes": {
|
||||||
|
"amplitude": [
|
||||||
|
{
|
||||||
|
"time": 0.42857142857142855,
|
||||||
|
"amplitude": 0,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 0.25,
|
||||||
|
"frequency": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4612427930813581,
|
||||||
|
"amplitude": 0,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 0.5,
|
||||||
|
"frequency": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4855861627162076,
|
||||||
|
"amplitude": 0,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 0.75,
|
||||||
|
"frequency": 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.5393978219090326,
|
||||||
|
"amplitude": 0,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 1,
|
||||||
|
"frequency": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frequency": [
|
||||||
|
{
|
||||||
|
"time": 0.42857142857142855,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4612427930813581,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4855861627162076,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.5393978219090326,
|
||||||
|
"frequency": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f26a3f5c6d14a44c196a2c50e54f37ec
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: dc84fb4fa9e67485a972c887d976d004, type: 3}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"major": 1,
|
||||||
|
"minor": 0,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"editor": "Haptic Editor",
|
||||||
|
"author": "Oliver",
|
||||||
|
"source": "new_au_coreplay_pour_less_1",
|
||||||
|
"project": "Magic_Sort",
|
||||||
|
"tags": [],
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"continuous": {
|
||||||
|
"envelopes": {
|
||||||
|
"amplitude": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"amplitude": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4426649583600256,
|
||||||
|
"amplitude": 0.15
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frequency": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"frequency": 0.0810719131614654
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.4426649583600256,
|
||||||
|
"frequency": 0.25
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ee687f540e1b84654a3ab68e821cd838
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: dc84fb4fa9e67485a972c887d976d004, type: 3}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"major": 1,
|
||||||
|
"minor": 0,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"editor": "Haptic Editor",
|
||||||
|
"author": "Oliver",
|
||||||
|
"source": "au_coreplay_pour_mid_1.wav",
|
||||||
|
"project": "Magic_Sort",
|
||||||
|
"tags": [],
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"continuous": {
|
||||||
|
"envelopes": {
|
||||||
|
"amplitude": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"amplitude": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.513,
|
||||||
|
"amplitude": 0.4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frequency": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.513,
|
||||||
|
"frequency": 0.4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc4f61e064f1440e3adc42cb52023fb9
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: dc84fb4fa9e67485a972c887d976d004, type: 3}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"major": 1,
|
||||||
|
"minor": 0,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"editor": "Haptic Editor",
|
||||||
|
"author": "Oliver",
|
||||||
|
"source": "au_coreplay_pour_more_1.wav",
|
||||||
|
"project": "Magic_Sort",
|
||||||
|
"tags": [],
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"continuous": {
|
||||||
|
"envelopes": {
|
||||||
|
"amplitude": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"amplitude": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.7,
|
||||||
|
"amplitude": 0.4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frequency": [
|
||||||
|
{
|
||||||
|
"time": 0,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.7,
|
||||||
|
"frequency": 0.5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a5e848c536ee74d9a9d7c1e782ffc106
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: dc84fb4fa9e67485a972c887d976d004, type: 3}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"major": 1,
|
||||||
|
"minor": 0,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"editor": "Haptic Editor",
|
||||||
|
"author": "Oliver",
|
||||||
|
"source": "au_coreplay_win.wav",
|
||||||
|
"project": "Magic_Sort",
|
||||||
|
"tags": [],
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"signals": {
|
||||||
|
"continuous": {
|
||||||
|
"envelopes": {
|
||||||
|
"amplitude": [
|
||||||
|
{
|
||||||
|
"time": 0.0006406149903907751,
|
||||||
|
"amplitude": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.05509288917360666,
|
||||||
|
"amplitude": 0.73,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 0.75,
|
||||||
|
"frequency": 0.25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.1646380525304292,
|
||||||
|
"amplitude": 0.26424694708276797
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.24407431133888532,
|
||||||
|
"amplitude": 1,
|
||||||
|
"emphasis": {
|
||||||
|
"amplitude": 1,
|
||||||
|
"frequency": 0.39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.7021140294682896,
|
||||||
|
"amplitude": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frequency": [
|
||||||
|
{
|
||||||
|
"time": 0.0006406149903907751,
|
||||||
|
"frequency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.05509288917360666,
|
||||||
|
"frequency": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.1646380525304292,
|
||||||
|
"frequency": 0.2472862957937585
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.24407431133888532,
|
||||||
|
"frequency": 0.7459294436906377
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 0.7021140294682896,
|
||||||
|
"frequency": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2dc504ef835db46b89c366c2b0650175
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: dc84fb4fa9e67485a972c887d976d004, type: 3}
|
||||||
@@ -520,6 +520,7 @@ GameObject:
|
|||||||
- component: {fileID: 519420031}
|
- component: {fileID: 519420031}
|
||||||
- component: {fileID: 519420029}
|
- component: {fileID: 519420029}
|
||||||
- component: {fileID: 519420030}
|
- component: {fileID: 519420030}
|
||||||
|
- component: {fileID: 519420033}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: MainCamera
|
||||||
@@ -645,6 +646,18 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &519420033
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 519420028}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a3d8ad76f12545caa287f26889c674e3, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
--- !u!1 &519563560
|
--- !u!1 &519563560
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1948,7 +1961,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 2ce47fe7df364a8fa37501256e5b5155, type: 3}
|
m_Script: {fileID: 11500000, guid: 2ce47fe7df364a8fa37501256e5b5155, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
targetGameState: 2
|
targetGameState: 4
|
||||||
enableLowpass: 0
|
enableLowpass: 0
|
||||||
buttonText: {fileID: 519563562}
|
buttonText: {fileID: 519563562}
|
||||||
--- !u!114 &1542973985
|
--- !u!114 &1542973985
|
||||||
@@ -2817,7 +2830,6 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 2093584671}
|
- component: {fileID: 2093584671}
|
||||||
- component: {fileID: 2093584670}
|
- component: {fileID: 2093584670}
|
||||||
- component: {fileID: 2093584672}
|
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: AudioSystem
|
m_Name: AudioSystem
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -2854,18 +2866,6 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!114 &2093584672
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 2093584669}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: a3d8ad76f12545caa287f26889c674e3, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!1660057539 &9223372036854775807
|
--- !u!1660057539 &9223372036854775807
|
||||||
SceneRoots:
|
SceneRoots:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ namespace OCES.Audio
|
|||||||
public static uint Play_Bar = 52;
|
public static uint Play_Bar = 52;
|
||||||
public static uint Play_Beat = 53;
|
public static uint Play_Beat = 53;
|
||||||
public static uint Play_Grid = 54;
|
public static uint Play_Grid = 54;
|
||||||
|
public static uint Play_au_coreplay_collect_handbag = 101;
|
||||||
|
public static uint Play_au_coreplay_win = 102;
|
||||||
|
public static uint Play_au_coreplay_pour_less = 103;
|
||||||
|
public static uint Play_au_coreplay_pour_mid = 104;
|
||||||
|
public static uint Play_au_coreplay_pour_more = 105;
|
||||||
} //public class Cues
|
} //public class Cues
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
@@ -68,6 +73,14 @@ namespace OCES.Audio
|
|||||||
{ "Bar", 52 },
|
{ "Bar", 52 },
|
||||||
{ "Beat", 53 },
|
{ "Beat", 53 },
|
||||||
{ "Grid", 54 },
|
{ "Grid", 54 },
|
||||||
|
{ "au_coreplay_collect_handbag", 101 },
|
||||||
|
{ "au_coreplay_win", 102 },
|
||||||
|
{ "au_coreplay_pour_less_1", 103 },
|
||||||
|
{ "au_coreplay_pour_less_2", 103 },
|
||||||
|
{ "au_coreplay_pour_mid_1", 104 },
|
||||||
|
{ "au_coreplay_pour_mid_2", 104 },
|
||||||
|
{ "au_coreplay_pour_more_1", 105 },
|
||||||
|
{ "au_coreplay_pour_more_2", 105 },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly HashSet<string> AmbiguousNames = new()
|
public static readonly HashSet<string> AmbiguousNames = new()
|
||||||
@@ -76,6 +89,12 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
public static readonly HashSet<string> SharedIdNames = new()
|
public static readonly HashSet<string> SharedIdNames = new()
|
||||||
{
|
{
|
||||||
|
"au_coreplay_pour_less_1",
|
||||||
|
"au_coreplay_pour_less_2",
|
||||||
|
"au_coreplay_pour_mid_1",
|
||||||
|
"au_coreplay_pour_mid_2",
|
||||||
|
"au_coreplay_pour_more_1",
|
||||||
|
"au_coreplay_pour_more_2",
|
||||||
};
|
};
|
||||||
} //public class NameDictionaries
|
} //public class NameDictionaries
|
||||||
|
|
||||||
@@ -99,6 +118,7 @@ namespace OCES.Audio
|
|||||||
Game, // 关卡内
|
Game, // 关卡内
|
||||||
Win, // 胜利
|
Win, // 胜利
|
||||||
Lose, // 失败
|
Lose, // 失败
|
||||||
|
Test,
|
||||||
}
|
}
|
||||||
|
|
||||||
} //public class Parameters
|
} //public class Parameters
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace OCES.Audio
|
|||||||
double m_startDspTime, m_secondsPerBeat; // 本次计数周期的起点
|
double m_startDspTime, m_secondsPerBeat; // 本次计数周期的起点
|
||||||
|
|
||||||
Coroutine m_beatCoroutine, m_barCoroutine, m_gridCoroutine;
|
Coroutine m_beatCoroutine, m_barCoroutine, m_gridCoroutine;
|
||||||
|
Coroutine m_delayCoroutine;
|
||||||
readonly Action<uint> m_onBeat, m_onBar, m_onGrid;
|
readonly Action<uint> m_onBeat, m_onBar, m_onGrid;
|
||||||
|
|
||||||
readonly MonoBehaviour m_host;
|
readonly MonoBehaviour m_host;
|
||||||
@@ -26,13 +27,13 @@ namespace OCES.Audio
|
|||||||
this.m_onGrid = onGrid;
|
this.m_onGrid = onGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Restart(MusicContainer container, float inheritedBpm, double dspTime)
|
internal void Restart(MusicContainer container, float inheritedBpm, double dspTime, double startOffset = 0d)
|
||||||
{
|
{
|
||||||
//Debug.Log($"[BeatClock] Restarting {container.Id}, inheritedBpm = {inheritedBpm}, dspTime = {dspTime}");
|
//Debug.Log($"[BeatClock] Restarting {container.Id}, inheritedBpm = {inheritedBpm}, dspTime = {dspTime}");
|
||||||
StopAll();
|
StopAll();
|
||||||
this.m_blendError = this.m_stopped = false;
|
this.m_blendError = this.m_stopped = false;
|
||||||
this.m_containerId = container.Id;
|
this.m_containerId = container.Id;
|
||||||
this.m_startDspTime = dspTime;
|
this.m_startDspTime = dspTime + startOffset;
|
||||||
|
|
||||||
// BPM:优先用自己的,为 0 则用传入的继承值
|
// BPM:优先用自己的,为 0 则用传入的继承值
|
||||||
float bpm = container.Bpm > 0f ? container.Bpm : inheritedBpm;
|
float bpm = container.Bpm > 0f ? container.Bpm : inheritedBpm;
|
||||||
@@ -57,6 +58,32 @@ namespace OCES.Audio
|
|||||||
this.m_barsPerGrid = container.Grid;
|
this.m_barsPerGrid = container.Grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double delay = this.m_startDspTime - AudioSettings.dspTime;
|
||||||
|
if (delay > 0)
|
||||||
|
{
|
||||||
|
this.m_delayCoroutine = this.m_host.StartCoroutine(DelayedStart(delay, hasTimeSig, hasGrid));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartCoroutines(hasTimeSig, hasGrid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator DelayedStart(double delay, bool hasTimeSig, bool hasGrid)
|
||||||
|
{
|
||||||
|
yield return new WaitUntil(() => AudioSettings.dspTime >= this.m_startDspTime - 0.02);
|
||||||
|
|
||||||
|
while (AudioSettings.dspTime < this.m_startDspTime)
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
if (this.m_stopped || this.m_blendError) yield break;
|
||||||
|
|
||||||
|
this.m_delayCoroutine = null;
|
||||||
|
StartCoroutines(hasTimeSig, hasGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartCoroutines(bool hasTimeSig, bool hasGrid)
|
||||||
|
{
|
||||||
// 分层启动协程
|
// 分层启动协程
|
||||||
// Beat:只要 BPM 有效就启动
|
// Beat:只要 BPM 有效就启动
|
||||||
this.m_beatCoroutine = this.m_host.StartCoroutine(BeatCoroutine());
|
this.m_beatCoroutine = this.m_host.StartCoroutine(BeatCoroutine());
|
||||||
@@ -82,10 +109,11 @@ namespace OCES.Audio
|
|||||||
internal void StopAll()
|
internal void StopAll()
|
||||||
{
|
{
|
||||||
this.m_stopped = true;
|
this.m_stopped = true;
|
||||||
if (this.m_beatCoroutine != null) this.m_host.StopCoroutine(this.m_beatCoroutine);
|
if (this.m_delayCoroutine != null) this.m_host.StopCoroutine(this.m_delayCoroutine);
|
||||||
if (this.m_barCoroutine != null) this.m_host.StopCoroutine(this.m_barCoroutine);
|
if (this.m_beatCoroutine != null) this.m_host.StopCoroutine(this.m_beatCoroutine);
|
||||||
if (this.m_gridCoroutine != null) this.m_host.StopCoroutine(this.m_gridCoroutine);
|
if (this.m_barCoroutine != null) this.m_host.StopCoroutine(this.m_barCoroutine);
|
||||||
this.m_beatCoroutine = this.m_barCoroutine = this.m_gridCoroutine = null;
|
if (this.m_gridCoroutine != null) this.m_host.StopCoroutine(this.m_gridCoroutine);
|
||||||
|
this.m_delayCoroutine = this.m_beatCoroutine = this.m_barCoroutine = this.m_gridCoroutine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal double GetNextDspTime(AlignMode mode)
|
internal double GetNextDspTime(AlignMode mode)
|
||||||
@@ -98,6 +126,11 @@ namespace OCES.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
double elapsed = now - this.m_startDspTime;
|
double elapsed = now - this.m_startDspTime;
|
||||||
|
if (elapsed < 0)
|
||||||
|
{
|
||||||
|
return this.m_startDspTime;
|
||||||
|
}
|
||||||
|
|
||||||
double period = mode switch
|
double period = mode switch
|
||||||
{
|
{
|
||||||
AlignMode.Beat => this.m_secondsPerBeat,
|
AlignMode.Beat => this.m_secondsPerBeat,
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ namespace OCES.Audio
|
|||||||
public double BaseDspTime; // 读取Source Segment 的 dspTime
|
public double BaseDspTime; // 读取Source Segment 的 dspTime
|
||||||
public int SampleRate; // Source Segment 的采样率
|
public int SampleRate; // Source Segment 的采样率
|
||||||
public bool Ready;
|
public bool Ready;
|
||||||
|
public double SourceStartOffset;
|
||||||
|
public double TargetAudioTime;
|
||||||
|
public double StartPlayTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -41,10 +44,12 @@ namespace OCES.Audio
|
|||||||
CurrentContainerId = containerId;
|
CurrentContainerId = containerId;
|
||||||
CurrentVolume = startVolume;
|
CurrentVolume = startVolume;
|
||||||
CurrentHandle = this.m_player.Play(containerId);
|
CurrentHandle = this.m_player.Play(containerId);
|
||||||
|
Debug.Log($"[ChannelFader] StartNew: containerId={containerId}, CurrentHandle={CurrentHandle}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopCurrent()
|
public void StopCurrent()
|
||||||
{
|
{
|
||||||
|
Debug.Log($"[ChannelFader] StopCurrent called! CurrentHandle={CurrentHandle}, stack=\n{Environment.StackTrace}");
|
||||||
StopHandle(CurrentHandle);
|
StopHandle(CurrentHandle);
|
||||||
CurrentHandle = null;
|
CurrentHandle = null;
|
||||||
CurrentContainerId = 0;
|
CurrentContainerId = 0;
|
||||||
@@ -84,7 +89,8 @@ namespace OCES.Audio
|
|||||||
/// 淡入分支:等待 FadeInOffset 后启动新音乐并淡入。
|
/// 淡入分支:等待 FadeInOffset 后启动新音乐并淡入。
|
||||||
/// 主协程 yield return 此分支,以便 DoTransition 在新音乐就绪后才结束。
|
/// 主协程 yield return 此分支,以便 DoTransition 在新音乐就绪后才结束。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, SyncPointState syncState = null, Action onContainerStarted = null)
|
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, SyncPointState syncState = null,
|
||||||
|
Action onContainerStarted = null)
|
||||||
{
|
{
|
||||||
if (transition?.FadeInOffset > 0f)
|
if (transition?.FadeInOffset > 0f)
|
||||||
{
|
{
|
||||||
@@ -94,7 +100,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
if (newContainerId == 0)
|
if (newContainerId == 0)
|
||||||
{
|
{
|
||||||
CurrentHandle = null;
|
CurrentHandle = null;
|
||||||
CurrentContainerId = 0;
|
CurrentContainerId = 0;
|
||||||
if (syncState != null) syncState.Ready = true;
|
if (syncState != null) syncState.Ready = true;
|
||||||
yield break;
|
yield break;
|
||||||
@@ -102,43 +108,63 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
float startVolume = transition?.FadeInTime > 0f ? 0f : 1f;
|
float startVolume = transition?.FadeInTime > 0f ? 0f : 1f;
|
||||||
StartNew(newContainerId, startVolume);
|
StartNew(newContainerId, startVolume);
|
||||||
|
onContainerStarted?.Invoke();
|
||||||
|
|
||||||
// SyncPoint: 获取新 Segment 的 AudioSource 并设置 timeSamples
|
switch (syncState)
|
||||||
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
|
||||||
{
|
{
|
||||||
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
// SyncPoint: 获取新 Segment 的 AudioSource 并设置 timeSamples
|
||||||
if (newSource && newSource.clip)
|
case { Mode: SyncPoint.SameAsCurrentSegment }:
|
||||||
{
|
{
|
||||||
// 计算从读取Source Segment 到现在经过的 samples
|
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||||
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
if (newSource && newSource.clip)
|
||||||
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
|
||||||
int targetTimeSamples = syncState.BaseTimeSamples + elapsedSamples;
|
|
||||||
|
|
||||||
if (targetTimeSamples < newSource.clip.samples)
|
|
||||||
{
|
{
|
||||||
newSource.timeSamples = targetTimeSamples;
|
double targetAudioTime = syncState.TargetAudioTime;
|
||||||
|
if (targetAudioTime > 0)
|
||||||
|
{
|
||||||
|
int targetTimeSamples = (int)(targetAudioTime * newSource.clip.frequency);
|
||||||
|
if (targetTimeSamples >= 0 && targetTimeSamples < newSource.clip.samples)
|
||||||
|
{
|
||||||
|
newSource.timeSamples = targetTimeSamples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError(
|
||||||
|
$"[ChannelFader] SyncPoint: 目标 samples({targetTimeSamples}) 超出范围 [0, {newSource.clip.samples}),降级为 Start");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 新音频 samples({newSource.clip.samples}) <= 目标 samples({targetTimeSamples}),降级为 Start");
|
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 未能获取新 Segment 的 AudioSource,降级为 Start");
|
||||||
}
|
}
|
||||||
|
syncState.Ready = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case { Mode: SyncPoint.Start, StartPlayTime: > 0 }:
|
||||||
{
|
{
|
||||||
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 未能获取新 Segment 的 AudioSource,降级为 Start");
|
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||||
|
if (!newSource || !newSource.clip)
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
//在赋值的时候减过fade in time了
|
||||||
|
int targetTimeSamples = (int)(syncState.StartPlayTime * newSource.clip.frequency);
|
||||||
|
|
||||||
|
if (targetTimeSamples >= 0 && targetTimeSamples < newSource.clip.samples)
|
||||||
|
{
|
||||||
|
newSource.timeSamples = targetTimeSamples;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
syncState.Ready = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onContainerStarted?.Invoke();
|
|
||||||
|
|
||||||
if (transition?.FadeInTime > 0f)
|
if (transition?.FadeInTime > 0f)
|
||||||
{
|
{
|
||||||
yield return this.m_coroutineHost.StartCoroutine(
|
yield return this.m_coroutineHost.StartCoroutine(
|
||||||
FadeIn(CurrentHandle, transition.FadeInTime));
|
FadeIn(CurrentHandle, transition.FadeInTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator FadeOut(ContainerPlayHandle handle, float fromVolume, float duration)
|
IEnumerator FadeOut(ContainerPlayHandle handle, float fromVolume, float duration)
|
||||||
{
|
{
|
||||||
//Debug.Log($"Fading out in {duration} seconds.");
|
//Debug.Log($"Fading out in {duration} seconds.");
|
||||||
|
|||||||
@@ -112,8 +112,9 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
bool isLoop = loopsCompleted > 0;
|
||||||
yield return this.m_coroutineHost.StartCoroutine(
|
yield return this.m_coroutineHost.StartCoroutine(
|
||||||
PlayContainerOnce(container, handle.TargetVolume, handle, effectiveBpm));
|
PlayContainerOnce(container, handle.TargetVolume, handle, effectiveBpm, isLoop));
|
||||||
|
|
||||||
if (handle.Cancelled) yield break;
|
if (handle.Cancelled) yield break;
|
||||||
|
|
||||||
@@ -139,7 +140,12 @@ namespace OCES.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 播放一个 Container 一轮(不含循环逻辑)
|
/// 播放一个 Container 一轮(不含循环逻辑)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerator PlayContainerOnce(MusicContainer container, float volumeScale, ContainerPlayHandle handle, float inheritedBpm)
|
IEnumerator PlayContainerOnce(
|
||||||
|
MusicContainer container,
|
||||||
|
float volumeScale,
|
||||||
|
ContainerPlayHandle handle,
|
||||||
|
float inheritedBpm,
|
||||||
|
bool isLoop = false)
|
||||||
{
|
{
|
||||||
if (container.Segments == null || container.Segments.Count == 0)
|
if (container.Segments == null || container.Segments.Count == 0)
|
||||||
yield break;
|
yield break;
|
||||||
@@ -151,11 +157,11 @@ namespace OCES.Audio
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ContainerType.Sequence:
|
case ContainerType.Sequence:
|
||||||
yield return PlaySequence(container, volumeScale, handle, inheritedBpm);
|
yield return PlaySequence(container, volumeScale, handle, inheritedBpm, isLoop);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ContainerType.Random:
|
case ContainerType.Random:
|
||||||
yield return PlayRandom(container, volumeScale, handle, inheritedBpm);
|
yield return PlayRandom(container, volumeScale, handle, inheritedBpm, isLoop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +217,12 @@ namespace OCES.Audio
|
|||||||
// Sequence
|
// Sequence
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
IEnumerator PlaySequence(MusicContainer container, float volumeScale, ContainerPlayHandle handle, float inheritedBpm)
|
IEnumerator PlaySequence(
|
||||||
|
MusicContainer container,
|
||||||
|
float volumeScale,
|
||||||
|
ContainerPlayHandle handle,
|
||||||
|
float inheritedBpm,
|
||||||
|
bool isLoop = false)
|
||||||
{
|
{
|
||||||
bool isStep = container.ContainerPlayMode;
|
bool isStep = container.ContainerPlayMode;
|
||||||
|
|
||||||
@@ -219,7 +230,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
// Step: 每次只播一个,游标全局推进
|
// Step: 每次只播一个,游标全局推进
|
||||||
int index = GetNextSequenceIndex(container);
|
int index = GetNextSequenceIndex(container);
|
||||||
yield return PlayChildAndWait(container.Segments[index], volumeScale, handle, inheritedBpm);
|
yield return PlayChildAndWait(container.Segments[index], volumeScale, handle, inheritedBpm, isLoop);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -233,7 +244,7 @@ namespace OCES.Audio
|
|||||||
if (i > 0 && container.StrategyParam > 0)
|
if (i > 0 && container.StrategyParam > 0)
|
||||||
yield return new WaitForSeconds(container.StrategyParam);
|
yield return new WaitForSeconds(container.StrategyParam);
|
||||||
|
|
||||||
yield return PlayChildAndWait(container.Segments[i], volumeScale, handle, inheritedBpm);
|
yield return PlayChildAndWait(container.Segments[i], volumeScale, handle, inheritedBpm, isLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +253,12 @@ namespace OCES.Audio
|
|||||||
// Random
|
// Random
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
IEnumerator PlayRandom(MusicContainer container, float volumeScale, ContainerPlayHandle handle, float inheritedBpm)
|
IEnumerator PlayRandom(
|
||||||
|
MusicContainer container,
|
||||||
|
float volumeScale,
|
||||||
|
ContainerPlayHandle handle,
|
||||||
|
float inheritedBpm,
|
||||||
|
bool isLoop = false)
|
||||||
{
|
{
|
||||||
bool isStep = container.ContainerPlayMode; // 同上,音乐系统默认 Continuous
|
bool isStep = container.ContainerPlayMode; // 同上,音乐系统默认 Continuous
|
||||||
|
|
||||||
@@ -250,7 +266,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
// Step Random: 随机选一个播放,算一次 loopCount
|
// Step Random: 随机选一个播放,算一次 loopCount
|
||||||
uint chosen = PickRandomChild(container);
|
uint chosen = PickRandomChild(container);
|
||||||
yield return PlayChildAndWait(chosen, volumeScale, handle, inheritedBpm);
|
yield return PlayChildAndWait(chosen, volumeScale, handle, inheritedBpm, isLoop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -268,7 +284,7 @@ namespace OCES.Audio
|
|||||||
if (container.StrategyParam > 0 && remaining.Count < container.Segments.Count - 1)
|
if (container.StrategyParam > 0 && remaining.Count < container.Segments.Count - 1)
|
||||||
yield return new WaitForSeconds(container.StrategyParam);
|
yield return new WaitForSeconds(container.StrategyParam);
|
||||||
|
|
||||||
yield return PlayChildAndWait(chosen, volumeScale, handle, inheritedBpm);
|
yield return PlayChildAndWait(chosen, volumeScale, handle, inheritedBpm, isLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,10 +296,14 @@ namespace OCES.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 播放一个子元素(segment 或 container),等待其完成后返回。
|
/// 播放一个子元素(segment 或 container),等待其完成后返回。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerator PlayChildAndWait(uint id, float volumeScale, ContainerPlayHandle parentHandle, float inheritedBpm)
|
IEnumerator PlayChildAndWait(uint id,
|
||||||
|
float volumeScale,
|
||||||
|
ContainerPlayHandle parentHandle,
|
||||||
|
float inheritedBpm,
|
||||||
|
bool isLoop = false)
|
||||||
{
|
{
|
||||||
bool done = false;
|
bool done = false;
|
||||||
ContainerPlayHandle child = PlayChild(id, volumeScale, () => done = true, inheritedBpm);
|
ContainerPlayHandle child = PlayChild(id, volumeScale, () => done = true, inheritedBpm, isLoop);
|
||||||
if (child != null)
|
if (child != null)
|
||||||
parentHandle.ChildHandles.Add(child);
|
parentHandle.ChildHandles.Add(child);
|
||||||
|
|
||||||
@@ -299,17 +319,17 @@ namespace OCES.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 启动一个子元素的播放,不等待,返回句柄。
|
/// 启动一个子元素的播放,不等待,返回句柄。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ContainerPlayHandle PlayChild(uint id, float volumeScale, Action onDone, float inheritedBpm)
|
ContainerPlayHandle PlayChild(uint id, float volumeScale, Action onDone, float inheritedBpm, bool isLoop = false)
|
||||||
{
|
{
|
||||||
// ID < 1000000 是 MusicSegment,否则是嵌套 Container
|
// ID < 1000000 是 MusicSegment,否则是嵌套 Container
|
||||||
return id < 1000000u ? PlaySegment(id, volumeScale, onDone) : Play(id, onDone, inheritedBpm: inheritedBpm);
|
return id < 1000000u ? PlaySegment(id, volumeScale, onDone, isLoop) : Play(id, onDone, inheritedBpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
// Segment 播放
|
// Segment 播放
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
ContainerPlayHandle PlaySegment(uint segmentId, float volumeScale, Action onFinished)
|
ContainerPlayHandle PlaySegment(uint segmentId, float volumeScale, Action onFinished, bool isLoop = false)
|
||||||
{
|
{
|
||||||
MusicSegment segment = this.m_segmentConfig.QueryById(segmentId);
|
MusicSegment segment = this.m_segmentConfig.QueryById(segmentId);
|
||||||
if (segment == null)
|
if (segment == null)
|
||||||
@@ -333,7 +353,12 @@ namespace OCES.Audio
|
|||||||
source.volume = volumeScale;
|
source.volume = volumeScale;
|
||||||
source.Play();
|
source.Play();
|
||||||
|
|
||||||
var handle = new ContainerPlayHandle();
|
if (isLoop && segment.StartOffset > 0)
|
||||||
|
{
|
||||||
|
source.time = (float)segment.StartOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerPlayHandle handle = new();
|
||||||
handle.ActiveSources.Add(source);
|
handle.ActiveSources.Add(source);
|
||||||
handle.Coroutine = this.m_coroutineHost.StartCoroutine(
|
handle.Coroutine = this.m_coroutineHost.StartCoroutine(
|
||||||
WaitSegmentFinish(source, handle, onFinished, segment.EndOffset));
|
WaitSegmentFinish(source, handle, onFinished, segment.EndOffset));
|
||||||
@@ -342,7 +367,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
IEnumerator WaitSegmentFinish(AudioSource source, ContainerPlayHandle handle, Action onFinished, double endOffset)
|
IEnumerator WaitSegmentFinish(AudioSource source, ContainerPlayHandle handle, Action onFinished, double endOffset)
|
||||||
{
|
{
|
||||||
double effectiveTime = endOffset > 0f ? source.clip.length - endOffset : 0f;
|
double effectiveTime = endOffset > 0f ? source.clip.length - endOffset : source.clip.length;
|
||||||
|
|
||||||
// 1. 等待"逻辑结束"(EndOffset 或自然结束)
|
// 1. 等待"逻辑结束"(EndOffset 或自然结束)
|
||||||
yield return new WaitWhile(() =>
|
yield return new WaitWhile(() =>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
readonly MusicContainerConfig m_containerConfig;
|
readonly MusicContainerConfig m_containerConfig;
|
||||||
readonly MusicTransitionConfig m_transitionConfig;
|
readonly MusicTransitionConfig m_transitionConfig;
|
||||||
|
readonly MusicSegmentConfig m_segmentConfig;
|
||||||
readonly MonoBehaviour m_coroutineHost;
|
readonly MonoBehaviour m_coroutineHost;
|
||||||
readonly ChannelFader m_fader;
|
readonly ChannelFader m_fader;
|
||||||
readonly BeatClock m_beatClock;
|
readonly BeatClock m_beatClock;
|
||||||
@@ -30,6 +31,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
internal MusicChannelPlayer(
|
internal MusicChannelPlayer(
|
||||||
MusicContainerConfig containerConfig,
|
MusicContainerConfig containerConfig,
|
||||||
|
MusicSegmentConfig segmentConfig,
|
||||||
MusicTransitionConfig transitionConfig,
|
MusicTransitionConfig transitionConfig,
|
||||||
LongAudioContainerPlayer player,
|
LongAudioContainerPlayer player,
|
||||||
MonoBehaviour coroutineHost,
|
MonoBehaviour coroutineHost,
|
||||||
@@ -39,6 +41,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
this.m_containerConfig = containerConfig;
|
this.m_containerConfig = containerConfig;
|
||||||
this.m_transitionConfig = transitionConfig;
|
this.m_transitionConfig = transitionConfig;
|
||||||
|
this.m_segmentConfig = segmentConfig;
|
||||||
this.m_coroutineHost = coroutineHost;
|
this.m_coroutineHost = coroutineHost;
|
||||||
this.m_fader = new ChannelFader(player, coroutineHost);
|
this.m_fader = new ChannelFader(player, coroutineHost);
|
||||||
this.m_beatClock = new BeatClock(coroutineHost, onBeat, onBar, onGrid);
|
this.m_beatClock = new BeatClock(coroutineHost, onBeat, onBar, onGrid);
|
||||||
@@ -55,6 +58,7 @@ namespace OCES.Audio
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal void SwitchTo(uint newContainerId)
|
internal void SwitchTo(uint newContainerId)
|
||||||
{
|
{
|
||||||
|
Debug.Log($"[MusicChannelPlayer] SwitchTo({newContainerId}): CurrentContainerId={this.m_fader.CurrentContainerId}, CurrentHandle={this.m_fader.CurrentHandle}");
|
||||||
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null)
|
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null)
|
||||||
return; // 已经在播目标,无需切换
|
return; // 已经在播目标,无需切换
|
||||||
|
|
||||||
@@ -110,6 +114,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
if (syncState.Mode == SyncPoint.SameAsCurrentSegment)
|
if (syncState.Mode == SyncPoint.SameAsCurrentSegment)
|
||||||
{
|
{
|
||||||
|
Debug.Log($"[MusicChannelPlayer] DoTransition L117: CurrentHandle={this.m_fader.CurrentHandle}, CurrentContainerId={this.m_fader.CurrentContainerId}");
|
||||||
// 旧 Container 不存在(如游戏首次启动),静默降级为 Start
|
// 旧 Container 不存在(如游戏首次启动),静默降级为 Start
|
||||||
if (this.m_fader.CurrentHandle == null)
|
if (this.m_fader.CurrentHandle == null)
|
||||||
{
|
{
|
||||||
@@ -129,6 +134,7 @@ namespace OCES.Audio
|
|||||||
syncState.BaseTimeSamples = oldSource.timeSamples;
|
syncState.BaseTimeSamples = oldSource.timeSamples;
|
||||||
syncState.BaseDspTime = AudioSettings.dspTime;
|
syncState.BaseDspTime = AudioSettings.dspTime;
|
||||||
syncState.SampleRate = oldSource.clip.frequency;
|
syncState.SampleRate = oldSource.clip.frequency;
|
||||||
|
syncState.SourceStartOffset = GetEffectiveStartOffset(this.m_currentContainer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -161,23 +167,46 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
MusicContainer container = this.m_containerConfig.QueryById(newContainerId);
|
MusicContainer container = this.m_containerConfig.QueryById(newContainerId);
|
||||||
float bpm = container.Bpm;
|
float bpm = container.Bpm;
|
||||||
|
|
||||||
// SyncPoint: BeatClock 用调整后的 dspTime,对齐到音频实际播放位置
|
double newStartOffset = GetEffectiveStartOffset(container);
|
||||||
double dspTime;
|
double dspTime;
|
||||||
|
|
||||||
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
||||||
{
|
{
|
||||||
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
||||||
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
||||||
double audioTime = (double)(syncState.BaseTimeSamples + elapsedSamples) / syncState.SampleRate;
|
double currentAudioTime = (double)(syncState.BaseTimeSamples + elapsedSamples) / syncState.SampleRate;
|
||||||
dspTime = AudioSettings.dspTime - audioTime;
|
// 当前的source播到了哪里
|
||||||
|
|
||||||
|
double currentLogicalTime = Math.Max(0, currentAudioTime - syncState.SourceStartOffset);
|
||||||
|
// EntryCue之后播了多少秒。要是小于0说明pre-entry还没播完。
|
||||||
|
|
||||||
|
double newAudioTime = currentLogicalTime + newStartOffset;
|
||||||
|
// 新Audio应该从多少秒开始播放
|
||||||
|
|
||||||
|
bool isPlayPreEntry = true; //TODO transition 是否播放pre-entry
|
||||||
|
syncState.TargetAudioTime = isPlayPreEntry ? currentLogicalTime + newStartOffset : currentLogicalTime;
|
||||||
|
dspTime = AudioSettings.dspTime - newAudioTime;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
double startPlayTime;
|
||||||
|
if (this.m_currentContainer == null)
|
||||||
|
{
|
||||||
|
startPlayTime = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double fadeInTime = transition?.FadeInTime ?? 0f;
|
||||||
|
startPlayTime = newStartOffset - fadeInTime;
|
||||||
|
startPlayTime = Math.Clamp(startPlayTime, 0, double.PositiveInfinity);
|
||||||
|
}
|
||||||
|
syncState.StartPlayTime = startPlayTime;
|
||||||
dspTime = AudioSettings.dspTime;
|
dspTime = AudioSettings.dspTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.m_currentContainer = container;
|
this.m_currentContainer = container;
|
||||||
this.m_beatClock.Restart(container, bpm, dspTime);
|
this.m_beatClock.Restart(container, bpm, dspTime, newStartOffset);
|
||||||
}));
|
}));
|
||||||
yield return this.m_currentFadeInCoroutine;
|
yield return this.m_currentFadeInCoroutine;
|
||||||
this.m_currentFadeInCoroutine = null;
|
this.m_currentFadeInCoroutine = null;
|
||||||
@@ -227,5 +256,26 @@ namespace OCES.Audio
|
|||||||
}
|
}
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GetEffectiveStartOffset(MusicContainer container)
|
||||||
|
{
|
||||||
|
if (container.ContainerType == ContainerType.Blend)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container.Segments is not { Count: > 0 })
|
||||||
|
return 0.0;
|
||||||
|
uint firstId = container.Segments[0];
|
||||||
|
if (firstId < 1000000u)
|
||||||
|
{
|
||||||
|
MusicSegment segment = this.m_segmentConfig.QueryById(firstId);
|
||||||
|
return segment?.StartOffset ?? 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicContainer child = this.m_containerConfig.QueryById(firstId);
|
||||||
|
return child != null ? GetEffectiveStartOffset(child) : 0.0;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace OCES.Audio
|
||||||
|
{
|
||||||
|
public partial class MusicSegmentConfig
|
||||||
|
{
|
||||||
|
// TODO: 运行前边界验证
|
||||||
|
// - MusicSegment.StartOffset <= AudioClip.length
|
||||||
|
// - MusicSegment.EndOffset <= AudioClip.length
|
||||||
|
// - MusicSegment.StartOffset + MusicSegment.EndOffset <= AudioClip.length
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c388a0ba2794e1ca09ccdde5bd5f99a
|
||||||
|
timeCreated: 1778049644
|
||||||
@@ -40,7 +40,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
this.m_stateRouter = new MusicStateRouter(musicPaths, ambiencePaths);
|
this.m_stateRouter = new MusicStateRouter(musicPaths, ambiencePaths);
|
||||||
this.m_musicChannel = new MusicChannelPlayer(
|
this.m_musicChannel = new MusicChannelPlayer(
|
||||||
containers, musicTransitions, longAudioContainerPlayer, this,
|
containers, segments, musicTransitions, longAudioContainerPlayer, this,
|
||||||
id => OnBeat?.Invoke(id),
|
id => OnBeat?.Invoke(id),
|
||||||
id => OnBar?.Invoke(id),
|
id => OnBar?.Invoke(id),
|
||||||
id => OnGrid?.Invoke(id));
|
id => OnGrid?.Invoke(id));
|
||||||
|
|||||||
Reference in New Issue
Block a user