Automatisera måttligt avancerad operation i W10. Hur bäst göra?

Permalänk
Medlem

Automatisera måttligt avancerad operation i W10. Hur bäst göra?

Jag har ett behov av att göra ett script eller automation (Windows 10) som kan generera textfiler, och sen ändra lite i texten dom textfilerna allt eftersom automationen framskrider. Annars, så måste jag utföra ett mardrömsjobb för hand, som kommer ta dagar, kanske veckor.

Jag söker lite support för bästa sätt att utföra det på.

Läget är följande: Jag har en mapp med över 7500 ljudfiler i. Ljudfilerna är organiserade i par (baserat på filnamn). Jag behöver spara 1 preset för varje ljudfils-par i mappen. För att göra detta, som läget är just nu, så måste jag använda en plugin i ett visst program. Jag öppnar pluginens GUI och drag'n'droppar in två ljudfiler in i pluginens GUI, och sen trycker jag på spara i plugin-GUI. Detta förmår pluginen att spara en preset. En preset består tekniskt sett av en XML-formaterad textfil i en specifik mapp på datorn.
Nu har jag gjort 1 st preset. Sen fortsätter jag, och gör samma sak igen, bara att nu tar jag dom nästkommande två ljudfilerna och drar in dom i GUI, och sparar preset igen. osv osv.. Såhär ska jag fortsätta, tills jag sparat preset för alla ljudfils-par som väntar i mappen. Sammanlagt 7760 stycken! Das is das problem.

Istället för att faktiskt utföra den mardrömmen manuellt, så tänker jag att man kanske kan få till ett script, som gör det här åt en, så skulle det spara några dagar eller veckor. Ett scriptet behöver inte använda det grafiska plugin GUI alls, utan kan bara fokusera på att generera dessa preset-filerna; alltså textfiler.

Vad scriptet i så fall behöver göra, är att skapa en textfil i en specifik mapp, och sen skriva in några rader XML-formaterad text i textfilen och spara detta. Texten som ska sparas i varje textfil är precis samma för varje fil, förutom på några enstaka ställen i XML-texten; nämligen namnen till dom separata ljudfilerna jag nämnde ovan.
Dom ljudfilerna är alla döpta med unika namn. Därför utgår jag från att scriptet borde göras så det läser av ljudfilernas filnamn, och sparar dom variabler eller liknande och kan sen ändra i texten för varje fil man gör. Varje preset-fil ska även sparas med ett filnamn utgående ifrån ljudfilernas namn.

Alltså..
- Läsa av ljudfilers namn (progressivt)
- Spara ljudfilsnamn i variabel
- (ev. omformattera ljudfilsnamn för att användas som filnamn)
- Skapa textfil döpt efter ljufdilsnamn
- Klistra in sparad textblock i den filen.
- Ersätta detaljer i texten med nya ljudfilsnamn från variabel ovan
- Spara
- repetera, repetera, repetera osv
- sluta när alla ljudfilder i mappen genomlöpts.

Jag är halvdan på batch-programmering. Jag brukar göra enklare batch-script i DOS-prompt och eller i powershell. Jag hänger med bra i att läsa och förstå kod, men att generera kod från scratch är betydligt svårare. Antar att vanligt Batch-script eller poswershell skulle kunna funka, men exakt vilka parametrar och design man skulle använda, har jag svårt att tänka mig.

Skulle det här vara möjligt? och i så fall hur kan man spara filnamn i variabler, sen ersätta viss text i textfiler med info från variabler?

Tackar för tips och åsikter.

Permalänk
Medlem

Du skriver att det är ljudfilspar, är det två olika extensions med samma filnamn , ligger de i samma mapp? Kan du ge exempel, path för fil 1, för fil 2, för xml-fil;
path1=c:\sf\001.mpg
path2=c:\sf\001.wav
pathxml=c:\sf\001.xml

Och innehållet i xml

<preset> <file1> <path> </path> </file1> <file2> <path> </path> </file2> </preset>

Permalänk
Medlem

Skulle kunna göra det som en console app i c#. Har du lite mer exempel på hur filnamnen ser ut och hur xmln ska vara?

Permalänk
Medlem

UIpath kanske kan fungera för dig? Det är ett RPA verktyg.

Permalänk
Avstängd

Powershell är utmärkt för sånt så varför krångla till det liksom.

Permalänk
Medlem
Skrivet av snajk:

Powershell är utmärkt för sånt så varför krångla till det liksom.

För mig är det betydligt enklare i c#, man är olika. TS kanske föredrar python? Tror batch blir knepigt men det går säkert.

Permalänk
Avstängd
Skrivet av Mordekai:

För mig är det betydligt enklare i c#, man är olika. TS kanske föredrar python? Tror batch blir knepigt men det går säkert.

Jo, men ps stöder ju c# mer eller mindre rakt av.

Permalänk
Medlem
Skrivet av Mordekai:

Du skriver att det är ljudfilspar, är det två olika extensions med samma filnamn , ligger de i samma mapp? Kan du ge exempel, path för fil 1, för fil 2, för xml-fil;
path1=c:\sf\001.mpg
path2=c:\sf\001.wav
pathxml=c:\sf\001.xml

Och innehållet i xml

Okej.

Det är ljudfiler, och dom ska operera tillsammans som par. Typ: ljudfil - 1a.wav och ljudfil - 1b, ljudfil - 2a.wav och ljudfil - 2b.wav
Alla ljudfiler ligger i samma mapp (sökväg). Sökvägen är en relativ sökväg som anges i preset-filen. Sökvägen från preset till ljudfilder, är "..\..\NV Responses\*.wav".

Ljudfilerna är organiserade i par. Och paren avskiljs INTE utav filändelser. Filtyp-namnet är samma (*.wav) för varje ljudfil; och *.atp för varjeXML-fil. Fil-paren är istället sammanlänkade via huruvida dom har A eller B i filnanet. A är den ena filen i filparet, och B är den andra:

T0 - 0.5s - D1 - A - log2.wav
T0 - 0.5s - D1 - B - log2.wav

Bokstaven A och B, i filnamnet, är dock inte alltid den sista bokstaven i filnamnet innan filändelsen. Ibland är det så, ibland inte. Det kan vara en grymt tillkrånglande faktor om an vill göra ett batch-script, jag inser det. Men det kan jag ändra, om så behövs. Möjligheten till om-organisation i filnamnen finns.

XML-texten som ska finnas i varje preset-fil, ser ut såhär (utom "---" som är ditlagt för avskild tydlighet):
---
<?xml version="1.0" encoding="UTF-8"?>

<FogConvolver_SETTINGS>
<STATE Stretch="0.5" PreDelay="0" Start="0" End="1" FadeIn="0" FadeOut="0"
FadeInCurve="0.5" FadeOutCurve="0.5" Reverse="0" PreGain="0.70999997854232788"
LowPass="1" HighPass="0" DryMix="0" WetMix="0.70999997854232788"
Bypass="0" TrueStereo="0.50999999046325684" StartInSamples="0"
EndInSamples="24000" StartInSamples2="0" EndInSamples2="24000"
WaveFile="..\..\NV Responses\T0 - 0.5s - D1 - A - lin.wav"
WaveFile2="..\..\NV Responses\T0 - 0.5s - D1 - B - lin.wav"/>
<ATTRIBUTES Category="T0" Tags="0.5 D1 lin " Rating="" Author=""/>
</FogConvolver_SETTINGS>
---

Den fulla sökvägen, från preset-fil till källfiler (ljudfiler), såsom den ska formuleras i preset-texter, ser ut såhär:

WaveFile="..\..\NV Responses\T0 - 0.5s - D1 - A - log2.wav"
WaveFile2="..\..\NV Responses\T0 - 0.5s - D1 - B - log2.wav"

Ljudfilerna är (för närvarande) döpta enligt följande konvention:
Parameter[egenskap] - [Parameter]s - Parameter - A eller B - tillägg.wav
Alltså:
T[0, 3, 6 eller 45] - 0.125s till 30.0s - D1 till D10 - A eller B - lin/log1/log2.wav

Det innebär alltså att alla ljudfiler är döpta efter samma konvention, och det enda som skiljer dom åt (och samtidigt parar iop dom ihophörande ljudfilerna) är huruvida dom heter A eller B i filnamnet. A och B hör ihop. Men annars inte.

Den text, i XML-texten i varje preset, som behövs ändras för varje preset, är förstås att ändra namnen på ljudfilerna (för varje preset) samt samt att skriva in ett nytt värde för parametern "Category" samt "Tags". "Tags" är dock inte total-nödvändigt, men Category är 100% nödvändigt att fylla i. "Category" och "Tags" i källtexten finns under en rad som har designationen "Attributes".

Textvärderdena i "Attributes" härrörs irån ljudfilernas filnamnn och ser ut typ såhär (för varje preset):

<ATTRIBUTES Category="T0" Tags="0.5 D1 log2" ... >

T0 - eller T* - härrörs ifrån dom första 2-3 bokstäverna i filnamnet. T* är också parametern för "Category".

Jag skulle kunna döpa om alla filerna efter en annan filnamn-konvention om så behövs, för att göra det lättare att ta ut detaljer ur filnamnen. t.ex. att lägga A och B som slutnamnet i varje fil.

Jag antar jag fått med det mesta nu (?)

Skrivet av Mordekai:

För mig är det betydligt enklare i c#, man är olika. TS kanske föredrar python? Tror batch blir knepigt men det går säkert.

Personligen skulle jag vara mer bekant med DOS batch eller powershell, pga rent erfarenhet. Men jag har hört att Python ska vara ovanligt lättläst och följsamt.

Permalänk

@Dooley: Vilket namn borde preset XML filen (.apt) filen få från exemplet ovan?

Permalänk
Medlem

Här är en konsollapplikation i C#. Kräver att den ligger och körs från platsen som hittar den relativa sökvägen. Kräver också en Xml-Mallfil

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Reflection; using System.Globalization; namespace BatchAudioFilter { class Program { static List<string> cats = new List<string>{"T0","T3","T6","T45"}; static List<string> param1 = new List<string> {"D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10" }; static List<string> type = new List<string> { "lin", "log1", "log2"}; static void Main(string[] args) { //string defXML= string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); string defXML = File.ReadAllText(Path.Combine(appPath, @DefaultFilter.xml)); string nVResponsePath = Path.Combine(appPath, @..\..NV Responses"); string[] aFiles = Directory.GetFiles(nVResponsePath, - A -"); foreach (string curAFile in aFiles) { FileInfo aFile = new FileInfo(curAFile); string aFileName = Path.GetFileNameWithoutExtension(aFile.FullName); if (IsValidAFile(aFileName)) { string curBFile = Path.Combine(aFile.DirectoryName, aFile.Name.Replace("- A -", "- B -")); if (File.Exists(curBFile)) { FileInfo bFile = new FileInfo(curBFile); string[] parts = aFileName.Split('-'); string curcat = parts[0].Trim().ToUpper(); double cursecondslong = SecondsLong(aFileName); string curparam = parts[2].Trim().ToUpper(); string curType = parts[4].Trim().ToLower(); string tags = String.Format(CultureInfo.InvariantCulture,"0.0#", cursecondslong) + " " + curparam + " " +curType + " "; string outXml = defXML.Replace("#¤F1¤#", aFile.Name); outXml = outXml.Replace("#¤F2¤#", bFile.Name); outXml = outXml.Replace("#¤C¤#", curcat); outXml = outXml.Replace("#¤N1¤#", tags); string oufilename = aFileName + ".atp"; string outpath = Path.Combine(nVResponsePath, oufilename); File.WriteAllText(outpath, outXml); } } } } static double SecondsLong(string fName) { string[] parts = fName.Split('-'); string seclen = parts[1].Trim().ToLower().Replace("s", ""); double secondslong = 0.0; bool test = double.TryParse(seclen, NumberStyles.Any, CultureInfo.InvariantCulture, out secondslong); if (test) { return secondslong; } else { return 0; } } static bool IsValidAFile(string fName) { string[] parts = fName.Split('-'); if (parts.Length!=5) { return false; } if (!cats.Contains(parts[0].Trim().ToUpper())) { return false; } string seclen = parts[1].Trim().ToLower().Replace("s", ""); double secondslong = 0.0; bool test = double.TryParse(seclen, NumberStyles.Any, CultureInfo.InvariantCulture, out secondslong); if (!test) { return false; } if (secondslong<0.5 || secondslong>30) { return false; } if (!param1.Contains(parts[2].Trim().ToUpper())) { return false; } if (!type.Contains(parts[4].Trim().ToLower())) { return false; } return true; } } }

XML-Mallfil i samma mapp med namnet DefaultFilter.xml

<?xml version="1.0" encoding="utf-8" ?> <FogConvolver_SETTINGS> <STATE Stretch="0.5" PreDelay="0" Start="0" End="1" FadeIn="0" FadeOut="0" FadeInCurve="0.5" FadeOutCurve="0.5" Reverse="0" PreGain="0.70999997854232788" LowPass="1" HighPass="0" DryMix="0" WetMix="0.70999997854232788" Bypass="0" TrueStereo="0.50999999046325684" StartInSamples="0" EndInSamples="24000" StartInSamples2="0" EndInSamples2="24000" WaveFile="..\..\NV Responses\#¤F1¤#" WaveFile2="..\..\NV Responses\#¤F2¤#"/> <ATTRIBUTES Category="#¤C¤#" Tags="#¤N1¤# " Rating="" Author=""/> </FogConvolver_SETTINGS>

Permalänk
Medlem

Skumt, några citattecken försvann, hade missat speca encoding.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Reflection; using System.Globalization; namespace BatchAudioFilter { class Program { static List<string> cats = new List<string>{"T0","T3","T6","T45"}; static List<string> param1 = new List<string> {"D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10" }; static List<string> type = new List<string> { "lin", "log1", "log2"}; static void Main(string[] args) { //string defXML= string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); string defXML = File.ReadAllText(Path.Combine(appPath, @DefaultFilter.xml),Encoding.UTF8); string nVResponsePath = Path.Combine(appPath, @..\..NV Responses"); string[] aFiles = Directory.GetFiles(nVResponsePath, *- A -*.wav"); foreach (string curAFile in aFiles) { FileInfo aFile = new FileInfo(curAFile); string aFileName = Path.GetFileNameWithoutExtension(aFile.FullName); if (IsValidAFile(aFileName)) { string curBFile = Path.Combine(aFile.DirectoryName, aFile.Name.Replace("- A -", "- B -")); if (File.Exists(curBFile)) { FileInfo bFile = new FileInfo(curBFile); string[] parts = aFileName.Split('-'); string curcat = parts[0].Trim().ToUpper(); double cursecondslong = SecondsLong(aFileName); string curparam = parts[2].Trim().ToUpper(); string curType = parts[4].Trim().ToLower(); string tags = String.Format(CultureInfo.InvariantCulture,"0.0#", cursecondslong) + " " + curparam + " " +curType + " "; string outXml = defXML.Replace("#¤F1¤#", aFile.Name); outXml = outXml.Replace("#¤F2¤#", bFile.Name); outXml = outXml.Replace("#¤C¤#", curcat); outXml = outXml.Replace("#¤N1¤#", tags); string oufilename = aFileName + ".atp"; string outpath = Path.Combine(nVResponsePath, oufilename); File.WriteAllText(outpath, outXml,Encoding.UTF8); } } } } static double SecondsLong(string fName) { string[] parts = fName.Split('-'); string seclen = parts[1].Trim().ToLower().Replace("s", ""); double secondslong = 0.0; bool test = double.TryParse(seclen, NumberStyles.Any, CultureInfo.InvariantCulture, out secondslong); if (test) { return secondslong; } else { return 0; } } static bool IsValidAFile(string fName) { string[] parts = fName.Split('-'); if (parts.Length!=5) { return false; } if (!cats.Contains(parts[0].Trim().ToUpper())) { return false; } string seclen = parts[1].Trim().ToLower().Replace("s", ""); double secondslong = 0.0; bool test = double.TryParse(seclen, NumberStyles.Any, CultureInfo.InvariantCulture, out secondslong); if (!test) { return false; } if (secondslong<0.5 || secondslong>30) { return false; } if (!param1.Contains(parts[2].Trim().ToUpper())) { return false; } if (!type.Contains(parts[4].Trim().ToLower())) { return false; } return true; } } }

Permalänk

@Dooley:

Ett annat exempel i C#

namespace FogConvolverPresetGenerator { using System; using System.Collections.Generic; using System.IO; using System.Linq; internal class Program { private static void Main() { // note: add support for arguments and help texts // note: add error handling // note: uses hardcoded relative paths for now // note: requires a Template.xml file in the same folder as the .exe file // note: supports any 'versions'.. not only A and B // question: Tags="0.5 D1 lin ", is the space in the end intended? // sample input files // "T0 - 0.5s - D1 - A - log1.wav" // "T0 - 0.5s - D1 - B - log1.wav" // "T0 - 0.5s - D1 - A - log2.wav" // "T0 - 0.5s - D1 - B - log2.wav" // "T1 - 0.5s - D1 - A - log1.wav" // "T1 - 0.5s - D1 - C - log1.wav" // output files is named // "T0 - 0.5s - D1 - log1.apt" // "T0 - 0.5s - D1 - log2.apt" // "T1 - 0.5s - D1 - log1.apt" const string relativeSourcePath = @..\..\NV Responses"; // 1) read all filenames var filePaths = Directory.GetFiles( relativeSourcePath, *.wav", SearchOption.TopDirectoryOnly); var fileNames = filePaths .Select(Path.GetFileNameWithoutExtension) .ToList(); Console.WriteLine($"Found {fileNames.Count} .wav files at relative path '{relativeSourcePath}'."); var pairs = new Dictionary<string, List<string>>(); foreach (var filename in fileNames) { var tokens = GetTokens( filename); // a sample key here is "T0 - 0.5s - D1 - log2" var key = $"{tokens[0]} - {tokens[1]} - {tokens[2]} - {tokens[4]}"; var value = tokens[3]; // 2) make pairs if (pairs.ContainsKey(key)) { pairs[key].Add(value); } else { pairs[key] = new List<string> { value }; } } // 3) load template var loadedTemplate = File.ReadAllText("Template.xml"); foreach (var pair in pairs) { var tokens = GetTokens( pair.Key); var orderedValues = pair.Value .OrderBy(x => x) .ToList(); // 4) replace tokens with values var relativeFile1 = BuildRelativeFilePath( relativeSourcePath, tokens, orderedValues[0]); var relativeFile2 = BuildRelativeFilePath( relativeSourcePath, tokens, orderedValues[1]); var preset = BuildPresetFile( loadedTemplate, relativeFile1, relativeFile2, tokens); var presetFilename = $"{tokens[0]} - {tokens[1]} - {tokens[2]} - {tokens[3]}"; // 5) write the preset file File.WriteAllText( $"{presetFilename}.apt", preset); } Console.WriteLine($"Done. Generated {pairs.Count} preset files."); } private static string BuildPresetFile( string template, string relativeFile1, string relativeFile2, IReadOnlyList<string> tokens) { var changed = template.Replace( "@FILE1", relativeFile1); changed = changed.Replace( "@FILE2", relativeFile2); changed = changed.Replace( "@CATEGORY", tokens[0]); // the 's' needs to be trimmed here var tags = $"{tokens[1].TrimEnd('s')} {tokens[2]} {tokens[3]}"; changed = changed.Replace( "@TAGS", tags); return changed; } private static List<string> GetTokens( string filename) { // extract values from filename // can use either regex or string split on '-' var tokens = filename .Split('-') .Select(x => x.Trim(' ')); return tokens.ToList(); } private static string BuildRelativeFilePath( string relativeSourcePath, IReadOnlyList<string> tokens, string orderedValues, string extension = "wav") { return Path.Combine( relativeSourcePath, $"{tokens[0]} - {tokens[1]} - {tokens[2]} - {orderedValues[0]} - {tokens[3]}.{extension}"); } } }

Behöver också en template i samma folder som .exe file med namn Template.xml

<?xml version="1.0" encoding="utf-8" ?> <FogConvolver_SETTINGS> <STATE Stretch="0.5" PreDelay="0" Start="0" End="1" FadeIn="0" FadeOut="0" FadeInCurve="0.5" FadeOutCurve="0.5" Reverse="0" PreGain="0.70999997854232788" LowPass="1" HighPass="0" DryMix="0" WetMix="0.70999997854232788" Bypass="0" TrueStereo="0.50999999046325684" StartInSamples="0" EndInSamples="24000" StartInSamples2="0" EndInSamples2="24000" WaveFile="@FILE1" WaveFile2="@FILE2"/> <ATTRIBUTES Category="@CATEGORY" Tags="@TAGS " Rating="" Author=""/> </FogConvolver_SETTINGS>

Svar på fel inlägg
Permalänk
Medlem

Detta lät ju kul!
Särskilt roligt att se så många som engarerar sig också!

Skrev ihop ett måttligt komplett skript i Python 3 som jag tror åstadkommer vad du vill: https://pastebin.com/se89zfqX

Jag utgick ifrån din exempel-mall för XML-filen. Mitt skript letar efter 'template.xml' och musikfilerna i samma mapp som det körs ifrån. Det kommer att skapa modifierade kopior utav mallen för varje par av musikfiler och spotta ur sig dom i en undermapp som döps till 'outputs'. Du kan också enkelt peka på en annan mall-fil när du kör skriptet, det enda den förlitar sig på just nu är att taggen 'STATE' med attributen 'WaveFile" och 'WaveFile2' samt taggen 'ATTRIBUTES' med attributen 'Category' och 'Tags' finns. Sökvägen ska även specas i 'WaveFile' och 'WaveFile2', där den sista delen av sökvägen byts ut mot respektive musikfils namn. Skriptet är även agnostiskt om vart i filnamnet A eller B befinner sig (så länge de finns på samma position för matchande filer) samt var taggarna finns

Vems lösning du än väljer så önskar jag dig lycka till, och jag hoppas detta sår ett frö hos någon som inser nyttan med att kunna programmera bort mycket manuellt arbete!

Permalänk
Medlem
Skrivet av Mordekai:

Skumt, några citattecken försvann, hade missat speca encoding.

Skrivet av zoomster2:

@Dooley:
Ett annat exempel i C#

Skrivet av Thesoxie:

Skrev ihop ett måttligt komplett skript i Python 3 som jag tror åstadkommer vad du vill: https://pastebin.com/se89zfqX

Oj, vilken härlig respons! Man får tacka så väldans.

Jag stöter dock på patrull på några ställen, när jag försöker kompilera C# (använder Visual Studio Code och .NET core). Tänkte prova C# först, men bara eftersom dom inkom först

Har problem med Mordekai's rader 21-23:
21: string defXML = File.ReadAllText(Path.Combine(appPath, @DefaultFilter.xml),Encoding.UTF8);
22: string nVResponsePath = Path.Combine(appPath, @..\..NV Responses");
23: string[] aFiles = Directory.GetFiles(nVResponsePath, *- A -*.wav");

Dels verkar det som koden betraktar "DefaultFilter" som en främmande designation (rad 21). Och på rader 22 och 23 så verkar det som programmet inte gillar formuleringen av sökvägen @..\..NV Responses" eller *- A -*.wav". Jag funderade lite på om det kunde bero på att det saknades ett citat-tecken där någonstans, för jag ser bara 1 ensamt citat-tecken i slutet. Men nu är jag inte så säker längre.

Samma problem verkar yttra sig i Zoomsters2s förslag:
rad 32: const string relativeSourcePath = @..\..\NV Responses";

Jag har försökt förstå mig runt hur jag kan lösa det problemet. Men det verkar som lösningen är över min kunskapsnivå i C#. Varje gång jag försöker kompilera så stannar builden med dessa problem som främsta anledning. Den externa XML-koden ligger dock på plats där den ska, men den ligger inte i CS-projektet eller i CS-projektets mapp.,

Undrar dessutom o inte sökvägen råkade bli lite felformulerad i Mordekais förslag? Den torde vara "..\..\NV Responses\"

Det som är viktigt med mapp-köret, är att preset-filer och ljudfiler ska ligga i olika mappar. Det är separationen som är viktig. Sen hur den separationen ser ut, det är mindre viktigt. Man kan t.ex. ha ljudfilerna i en undermapp till den mapp som presetsen ligger i. Eller liknande. Då blir kanske sökvägen lättare att formulera. Men sökvägen mellan dom två mapparna bör vara relativ, så man kan flytta mapparna till andra ställen på datorn, utan att behöva skriva om 7760 filer igen.

Skrivet av zoomster2:

@Dooley: Vilket namn borde preset XML filen (.apt) filen få från exemplet ovan?

Jag glömde det. Sorry. Det vore trevligast om preseten kunde få ett filnamn baserat på nuvarande ljudfilernas namn, som för närvarande är formulerade typ såhär:

T0 - 0.5s - D1 - A - log2.wav

Om man kan utelämna T* värdet i början, samt ta bort "A" och "B" i filnamnet, och filtypsbeskrivningen ".wav". Då blir filnamnet typ 0.5s D1 log2. Det vore optimalt. T-värdet ska ändå hamna inne i preset-filen, så det värdet kommer synas på rätt sätt ändå när man använder det.
Det var det här jag menade, när jag skrev att man skulle kunna döpa om filerna enligt ett annat mönster, för sättet dom är döpta på nu gör det nog extra kråpngligt att formattera till filnamnet på det sätt jag menar är optimalt (?)
Men jag kan eventuellt döpa om dom med batch-verktyg efteråt med, det blir nog enklare för alla parter (utom mig).

I kodkommentarerna så frågar du också:
"question: Tags="0.5 D1 lin ", is the space in the end intended?"
.. och svaret på det är Nej. Det extra mellanslaget ska inte vara där.

Permalänk

@Dooley: Här en länk till C# projektet.
https://1drv.ms/u/s!AteR6WzVnVaLggTCKxDm7WWOQcud?e=pMASF4

På rad 98 ändrar du formatet på .apt namnet

// token[0] = "T0"
// token[1] = "0.5s"
// token[2] = "D1"
// token[3] = "log1"
var presetFilename = $"{tokens[0]} - {tokens[1]} - {tokens[2]} - {tokens[3]}";

Så byt till
var presetFilename = $"{tokens[1]} - {tokens[2]} - {tokens[3]}";
för
"0.5s - D1 - log1"

Och ja, verkar att vissa tecken försvinner vid copy & paste.
@..\..\NV Responses";
ska ha ett " efter @

Och
*.wav"
ska vara
"*.wav"

Permalänk

@Dooley: Om du vill använda en dynamisk path när du kör programmet så ändra till detta

private static void Main(string[] args) { var relativeSourcePath = "..\\..\\NV Responses"; if (args != null && args.Any()) { relativeSourcePath = args[0]; }

Och kör detta för ett exempel på bara en folder nivå ner istället för två nivåer relativt
FogConvolverPresetGenerator.exe "..\NV Responses"

eller använd absolut path
FogConvolverPresetGenerator.exe "C:\code\samples\FogConvolverPresetGenerator\FogConvolverPresetGenerator\NV Responses"

Permalänk
Medlem
Skrivet av Dooley:

Oj, vilken härlig respons! Man får tacka så väldans.

Jag stöter dock på patrull på några ställen, när jag försöker kompilera C# (använder Visual Studio Code och .NET core). Tänkte prova C# först, men bara eftersom dom inkom först

Har problem med Mordekai's rader 21-23:
21: string defXML = File.ReadAllText(Path.Combine(appPath, @DefaultFilter.xml),Encoding.UTF8);
22: string nVResponsePath = Path.Combine(appPath, @..\..NV Responses");
23: string[] aFiles = Directory.GetFiles(nVResponsePath, *- A -*.wav");

Dels verkar det som koden betraktar "DefaultFilter" som en främmande designation (rad 21). Och på rader 22 och 23 så verkar det som programmet inte gillar formuleringen av sökvägen @..\..NV Responses" eller *- A -*.wav". Jag funderade lite på om det kunde bero på att det saknades ett citat-tecken där någonstans, för jag ser bara 1 ensamt citat-tecken i slutet. Men nu är jag inte så säker längre.

Samma problem verkar yttra sig i Zoomsters2s förslag:
rad 32: const string relativeSourcePath = @..\..\NV Responses";

Jag har försökt förstå mig runt hur jag kan lösa det problemet. Men det verkar som lösningen är över min kunskapsnivå i C#. Varje gång jag försöker kompilera så stannar builden med dessa problem som främsta anledning. Den externa XML-koden ligger dock på plats där den ska, men den ligger inte i CS-projektet eller i CS-projektets mapp.,

Undrar dessutom o inte sökvägen råkade bli lite felformulerad i Mordekais förslag? Den torde vara "..\..\NV Responses\"

Det som är viktigt med mapp-köret, är att preset-filer och ljudfiler ska ligga i olika mappar. Det är separationen som är viktig. Sen hur den separationen ser ut, det är mindre viktigt. Man kan t.ex. ha ljudfilerna i en undermapp till den mapp som presetsen ligger i. Eller liknande. Då blir kanske sökvägen lättare att formulera. Men sökvägen mellan dom två mapparna bör vara relativ, så man kan flytta mapparna till andra ställen på datorn, utan att behöva skriva om 7760 filer igen.

Jag glömde det. Sorry. Det vore trevligast om preseten kunde få ett filnamn baserat på nuvarande ljudfilernas namn, som för närvarande är formulerade typ såhär:

T0 - 0.5s - D1 - A - log2.wav

Om man kan utelämna T* värdet i början, samt ta bort "A" och "B" i filnamnet, och filtypsbeskrivningen ".wav". Då blir filnamnet typ 0.5s D1 log2. Det vore optimalt. T-värdet ska ändå hamna inne i preset-filen, så det värdet kommer synas på rätt sätt ändå när man använder det.
Det var det här jag menade, när jag skrev att man skulle kunna döpa om filerna enligt ett annat mönster, för sättet dom är döpta på nu gör det nog extra kråpngligt att formattera till filnamnet på det sätt jag menar är optimalt (?)
Men jag kan eventuellt döpa om dom med batch-verktyg efteråt med, det blir nog enklare för alla parter (utom mig).

I kodkommentarerna så frågar du också:
"question: Tags="0.5 D1 lin ", is the space in the end intended?"
.. och svaret på det är Nej. Det extra mellanslaget ska inte vara där.

Problemet är att slumpmässiga citattecken försvinner trots att vi använder Code-taggar. Nu gick min dator sönder igår så får inte tillgång till källfilerna på några dagar.

Permalänk
Medlem
Skrivet av Dooley:

...
Det som är viktigt med mapp-köret, är att preset-filer och ljudfiler ska ligga i olika mappar. Det är separationen som är viktig. Sen hur den separationen ser ut, det är mindre viktigt. Man kan t.ex. ha ljudfilerna i en undermapp till den mapp som presetsen ligger i. Eller liknande. Då blir kanske sökvägen lättare att formulera. Men sökvägen mellan dom två mapparna bör vara relativ, så man kan flytta mapparna till andra ställen på datorn, utan att behöva skriva om 7760 filer igen.

Jag glömde det. Sorry. Det vore trevligast om preseten kunde få ett filnamn baserat på nuvarande ljudfilernas namn, som för närvarande är formulerade typ såhär:

T0 - 0.5s - D1 - A - log2.wav

Om man kan utelämna T* värdet i början, samt ta bort "A" och "B" i filnamnet, och filtypsbeskrivningen ".wav". Då blir filnamnet typ 0.5s D1 log2. Det vore optimalt. T-värdet ska ändå hamna inne i preset-filen, så det värdet kommer synas på rätt sätt ändå när man använder det.
Det var det här jag menade, när jag skrev att man skulle kunna döpa om filerna enligt ett annat mönster, för sättet dom är döpta på nu gör det nog extra kråpngligt att formattera till filnamnet på det sätt jag menar är optimalt (?)
Men jag kan eventuellt döpa om dom med batch-verktyg efteråt med, det blir nog enklare för alla parter (utom mig).

...

Uppdaterade mitt skript enligt ditt förslag om hur man ska döpa preset-filerna den spottar ur sig. Exempelvis döps preset-filen för 'T0 - 0.5s - D1 - A - log2.wav' till '0.5s D1 log2.xml'

I övrigt tror jag redan att det uppfyller allt du sagt då alla nyskapade preset-filer hamnar i en undermapp till mappen med musikfilerna och därmed håller dom separerade. Den relativa sökvägen får du just nu skriva in själv i template.xml filen, men jag skulle kunna lägga till funktionallitet så att du kan peka på mappen med musikfilerna samt mappen där du vill spotta ur dig preset-filerna och låta skriptet lista ut den relativa sökvägen interaktivt mellan dessa Keep us updated!

Länk till skriptet: https://pastebin.com/SikatCP4

Permalänk
Medlem

Ni är så snälla så man får diabetes. Jag kommer att ha att lära mig ifrån era exempel i veckor framöver

Så nu känner jag mig sååå jobbig, men jag försöker verkligen! Vid kompilering fick jag först problem med "ERROR CS1056 unexpected character '$'", ett helt okänt problem för mig. Så jag ansträngde mig som f*n för att försöka lösa det, och med en inte så liten möda (pust) så gick det. Använder Visual Studio Code och .Net core 3.1 just nu.

Sen valde jag att ha ljudfilerna i undermappen NV_Responses, så jag skrev in det korrekt i koden (i Zoomster2s förslag:

const string relativeSourcePath = @ "NV_Responses\"; (mellanslag tillagt för att undgå swec's forumformattering

Jag kompilerar Zoomster2s förslag och kör programmet helt enkligt instruktion. Men det avbryts, på grund av ett fel som helt enkelt är för svårtytt för mig. Jag återger promptens output ordagrant här, och den indikerar att programmet genomlöps åtminstone fram till kodrad 44:

Found 7760 .wav files at relative path 'NV_Responses\'. Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') at FogconvolverPresetGenerator.Program.Main()

Mordekai's exempel kan jag inte kompilera i VS Code, eftersom kompilatorn inte förstår "@DefaultFilter.xml".
Outputten vid kompileringsförsök är som nedan. Jag antar att man kanske borde lägga in någon rad i Propertygroup i projektets *.csproj fil?

Program.cs(21,68): error CS0103: The name 'DefaultFilter' does not exist in the current context

Python ska jag försöka med nu strax.

Permalänk
Medlem

Insåg att mitt skript inte spottade ur sig någon XML-deklaration i början av varje nyskapt preset-fil, så uppdaterade det ännu en gång

https://pastebin.com/WS5dih0W

Permalänk

Jag önskar att jag hade nåt att tillägga, men eftersom jag hade fulat till nåt i AHK så har du redan fått bättre hjälp. Men jag undrar vad det är som gjort att du får dras med den här processen från första början?

Visa signatur

Dator: ja
Tillbehör: ja

Permalänk
Medlem
Skrivet av Thesoxie:

Insåg att mitt skript inte spottade ur sig någon XML-deklaration i början av varje nyskapt preset-fil, så uppdaterade det ännu en gång

Chef!

Python scriptet funkade rakt av. Åtminstone funktionellt.
Några detaljer ska jag försöka justera nu, främst sökväg och detaljer i XML. Det är inte ditt fel alls, utan det är jag som inte tänkt till innan jag talat

Jag ska vara lite fördomsfull här och säga att jag gillar inte Microsoft överlag. Dom har en del riktigt bra idéer, ofta ifråga om teknisk infrastruktur. Men dom har oftast horribla implementeringar av dom idéerna. Jag tycker man får alltid påtagligt mycket kompatibilitetskonflikter, småfel, överlag en massa extra tidsödande sidoarbete med Microsofts mjukvarulösningar, som man inte får när man använder liknande lösningar från andra upphovshåll - tycker jag. Att Python scriptet funkade rakt av, och att C# koden hängde upp sig på flera svårtolkade petitesser på rad, det tycker jag är en reflektion av precis detta. Det är garanterat inte kodskaparnas fel här. Jag skulle gissa att Python helt enkelt kräver betydligt mindre hänsyn till omkringliggande detaljer och beroenden, jämfört med Visual Studio och .Net sfären. "Fanskapet bah funkar, typ!". Sen får man väl stå ut med att det är ett tolkat språk och inte kompilerat, så det är segare i exekveringen. Men det är inte first person shooter det är fråga om här.

Skrivet av Role_Model:

Jag önskar att jag hade nåt att tillägga, men eftersom jag hade fulat till nåt i AHK så har du redan fått bättre hjälp.

Man tackar för omtanken ändå. Jag är fett tacksam för hjälpen här

Skrivet av Role_Model:

Men jag undrar vad det är som gjort att du får dras med den här processen från första början?

Hur menar du då? Tänker du på vad exakt det är för process som jag pysslar med, det där med ljudfiler och presets?
Eller menar du hur jag hamnade i läget att jag bad om programmeringshjälp överhuvudtaget?

Jag har sett att tråden blivit rejält läst. Det var inte min mening att göra så stor grej av det eller ta upp plats. Hoppas andra kan lära av detaljer här med.

Permalänk
Medlem
Skrivet av Dooley:

Några detaljer ska jag försöka justera nu, främst sökväg och detaljer i XML. Det är inte ditt fel alls, utan det är jag som inte tänkt till innan jag talat

F*n. Ser inte ut som jag klarar av det själv.

Sökvägen till ljudfilerna, skrivs nu in i XML-filerna som att ljudfilerna kommer ligga i samma mapp som XML.-filerna. Såhär:

WaveFile="T0 - 0.5s - D1 - A - lin.wav"

Men ljudfilerna kommer ligga i en undermapp som heter NV_Responses. Därför vore det bra om sökvägen kunde skrivas in i XML-filerna som ..

WaveFile="NV_Responses\T0 - 0.5s - D1 - A - lin.wav"

Jag är nästan helt novis på Python, men jag hade hoppats på att kunna trycka in en textvariabel med värdet "NV_Responses\" och kombinera den med den variabel som lagrar filnamnet, i din kod. Men du har varit så duktig så de flesta referenser och värden hämtas via funktioner, plus att filnamnen är så splittade och parshade nu, och då blir jag rätt tappad i just Python.

EDIT: Jo, tamigfasen, jag kunde. Blev ett noob-hack, men vad fasen kan man förvänta sig
Jag deklarerade variabeln Subfolder = "NV_Responses" för hela skriptet, och sen lyckades jag klura ut var filnamnen anges. Rad 62 och 63:

# Write changes to XML tree state.set(first_attribute_id, new_first_attribute) state.set(second_attribute_id, new_second_attribute)

.. och lade till subfolder-variabeln där ...

# Write changes to XML tree state.set(first_attribute_id, subfolder + "/" + new_first_attribute) state.set(second_attribute_id, subfolder + "/" + new_second_attribute)

Som sagt, fulhack, men vafasen.

Permalänk
Skrivet av Dooley:

Man tackar för omtanken ändå. Jag är fett tacksam för hjälpen här
Hur menar du då? Tänker du på vad exakt det är för process som jag pysslar med, det där med ljudfiler och presets?
Eller menar du hur jag hamnade i läget att jag bad om programmeringshjälp överhuvudtaget?

Jag har sett att tråden blivit rejält läst. Det var inte min mening att göra så stor grej av det eller ta upp plats. Hoppas andra kan lära av detaljer här med.

Jag tänkte mest på processen med ljudfiler och presets, ursäkta om jag var otydlig. Typ "jag vill göra en virtuel stereo-fil av två mono-filer" eller nåt.

Visa signatur

Dator: ja
Tillbehör: ja

Permalänk
Medlem
Skrivet av Dooley:

Sökvägen till ljudfilerna, skrivs nu in i XML-filerna som att ljudfilerna kommer ligga i samma mapp som XML.-filerna. Såhär:

WaveFile="T0 - 0.5s - D1 - A - lin.wav"

Men ljudfilerna kommer ligga i en undermapp som heter NV_Responses. Därför vore det bra om sökvägen kunde skrivas in i XML-filerna som ..

WaveFile="NV_Responses\T0 - 0.5s - D1 - A - lin.wav"

....

Detta är någonting som du kan skriva in direkt i 'template.xml' annars, du ska inte behöva göra några ändringar i koden ö.h.t Jag skulle tro att det löser sig om du i 'template.xml' sätter följande värden:

WaveFile="NV_Responses\" WaveFile2="NV_Responses\"

Så mitt förslag på en fullständig mall för ditt ändamål:

<?xml version="1.0" encoding="utf-8"?> <FogConvolver_SETTINGS> <STATE Stretch="0.5" PreDelay="0" Start="0" End="1" FadeIn="0" FadeOut="0" FadeInCurve="0.5" FadeOutCurve="0.5" Reverse="0" PreGain="0.70999997854232788" LowPass="1" HighPass="0" DryMix="0" WetMix="0.70999997854232788" Bypass="0" TrueStereo="0.50999999046325684" StartInSamples="0" EndInSamples="24000" StartInSamples2="0" EndInSamples2="24000" WaveFile="NV_Responses\" WaveFile2="NV_Responses\spelar ingen roll vad du skriver in här" /> <ATTRIBUTES Category="T0" Tags="0.5 D1 lin" Rating="" Author="" /> </FogConvolver_SETTINGS>

Det som händer i original-skriptet är att allt efter sista 'katalogavskiljaren' (directory separator, '\' i windows ) i 'WaveFile' respektive 'WaveFile2'-taggen byts ut mot namnen på musikfilerna

Återkom gärna efter att du prövat detta!

Edit: Såg att du petat in forward-slash (/) i din modifierade kod. Detta kommer ju inte att bli rätt i en windows-miljö när du ska referera till lokala filer, så jag föreslår att du ändrar tillbaks koden och ser till att du använder rätt avskjiljare i 'template.xml' istället.

Skriptet tar hänsyn till vilken plattform du använder, vilket innebär att du inte ska behöva hårdkoda in plattformsberoende avskiljare i koden. Det i sin tur innebär dock att du behöver ha två olika mallar för windows respektive MacOS/Linux, men det är enkelt att skicka in en alternativ mall som argument till skriptet, exempelvis:

python preset-creator.py linux-template.xml

Permalänk
Medlem
Skrivet av Role_Model:

Jag tänkte mest på processen med ljudfiler och presets, ursäkta om jag var otydlig. Typ "jag vill göra en virtuel stereo-fil av två mono-filer" eller nåt.

Aha. Ja det kan nog se lite konstigt ut.

Det är en ljudeffekt, som man använder bland annat vid avancerat ljud för video och spel och liknande. Det är en process som utför 'merge'-ning av flera olika ljud. Man tar 1 grundljud, och skickar det att bli kraftigt färgat eller påverkat genom ett annat ljud (eller kombinationen av flera andra ljud).

Ljudeffekten, som jag behövde presets för, är en sån process som kör 1 ljudfil genom en annan (eller summan av flera andra). Fördelarna med att summera flera olika filer, och använda den summan som det som påverkar det genomlöpande ljudet, är att stereobilden, djupkänslan och detaljrikedomen blir bättre.

Det är väl det bästa jag kan förklara, kortfattat

Permalänk
Skrivet av Dooley:

Det är väl det bästa jag kan förklara, kortfattat

Jag har pysslat med videoredigering på hobbynivå och där kommer ju även ljud in i bilden (höhö), så jag förstår precis vad du menar, även om jag själv aldrig var på den nivån. Det stillade min nyfikenhet, tack.

Visa signatur

Dator: ja
Tillbehör: ja