├── .gitignore
├── BuildConsole
├── App.config
├── App.ico
├── BuildConsole.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── License
├── QuickWaveBank.sln
├── QuickWaveBank
├── App.config
├── App.ico
├── App.xaml
├── App.xaml.cs
├── Commands.cs
├── Config.cs
├── Controls
│ ├── IntSpinner.xaml
│ └── IntSpinner.xaml.cs
├── DragAndDrop
│ ├── DragAdorner.cs
│ ├── ListViewDragDropManager.cs
│ └── MouseUtilities.cs
├── Extracting
│ ├── ADPCMConverter.cs
│ ├── FFmpeg.cs
│ ├── TerrariaLocator.cs
│ └── WaveBankExtractor.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── QuickWaveBank.csproj
├── Resources
│ ├── Icons
│ │ ├── About.png
│ │ ├── Advanced.png
│ │ ├── AppError.ico
│ │ ├── Browse.png
│ │ ├── BuildWaveBank.png
│ │ ├── Compression.png
│ │ ├── Convert.png
│ │ ├── Credits.png
│ │ ├── DragAndDrop.png
│ │ ├── Empty.png
│ │ ├── ErrorIcon.png
│ │ ├── Exit.png
│ │ ├── ExtractWaveBank.png
│ │ ├── Github.png
│ │ ├── Help.png
│ │ ├── InfoIcon.png
│ │ ├── LoadList.png
│ │ ├── MoveDown.png
│ │ ├── MoveUp.png
│ │ ├── NewWaveList.png
│ │ ├── Next.png
│ │ ├── Pause.png
│ │ ├── PauseUnflipped.png
│ │ ├── Play.png
│ │ ├── PlayUnflipped.png
│ │ ├── Previous.png
│ │ ├── QuestionIcon.png
│ │ ├── SaveConfirmation.png
│ │ ├── SaveList.png
│ │ ├── SaveListAs.png
│ │ ├── ShowLog.png
│ │ ├── Stop.png
│ │ ├── Streaming.png
│ │ ├── TerrariaIcon.png
│ │ ├── TrackNames.png
│ │ ├── VolumeHigh.png
│ │ ├── VolumeLow.png
│ │ ├── VolumeMute.png
│ │ ├── VolumeNone.png
│ │ ├── WarningIcon.png
│ │ ├── WaveAdd.png
│ │ ├── WaveAddFolder.png
│ │ ├── WaveBank.png
│ │ ├── WaveRemove.png
│ │ └── WaveRemoveAll.png
│ ├── Logo112.png
│ ├── WaveBankProject.xap
│ └── ffmpeg.exe
├── Util
│ ├── EmbeddedResources.cs
│ └── Extensions.cs
├── Windows
│ ├── AboutWindow.xaml
│ ├── AboutWindow.xaml.cs
│ ├── CompressionDialog.xaml
│ ├── CompressionDialog.xaml.cs
│ ├── CreditsWindow.xaml
│ ├── CreditsWindow.xaml.cs
│ ├── ErrorLogWindow.xaml
│ ├── ErrorLogWindow.xaml.cs
│ ├── ErrorMessageBox.xaml
│ ├── ErrorMessageBox.xaml.cs
│ ├── FolderBrowserLauncher.cs
│ ├── TriggerMessageBox.xaml
│ ├── TriggerMessageBox.xaml.cs
│ ├── VolumeDialog.xaml
│ └── VolumeDialog.xaml.cs
├── Xap
│ ├── XapFile.cs
│ ├── XapGroup.cs
│ └── XapVariable.cs
├── document-convert.png
├── document-music-playlist.png
├── folder-open-document-music-playlist.png
├── music.png
└── packages.config
└── Readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | XactBld3.exe
7 |
8 | # User-specific files
9 | *.suo
10 | *.user
11 | *.userosscache
12 | *.sln.docstates
13 |
14 | # User-specific files (MonoDevelop/Xamarin Studio)
15 | *.userprefs
16 |
17 | # Build results
18 | [Dd]ebug/
19 | [Dd]ebugPublic/
20 | [Rr]elease/
21 | [Rr]eleases/
22 | x64/
23 | x86/
24 | bld/
25 | [Bb]in/
26 | [Oo]bj/
27 | [Ll]og/
28 |
29 | # Visual Studio 2015 cache/options directory
30 | .vs/
31 | # Uncomment if you have tasks that create the project's static files in wwwroot
32 | #wwwroot/
33 |
34 | # MSTest test Results
35 | [Tt]est[Rr]esult*/
36 | [Bb]uild[Ll]og.*
37 |
38 | # NUNIT
39 | *.VisualState.xml
40 | TestResult.xml
41 |
42 | # Build Results of an ATL Project
43 | [Dd]ebugPS/
44 | [Rr]eleasePS/
45 | dlldata.c
46 |
47 | # .NET Core
48 | project.lock.json
49 | project.fragment.lock.json
50 | artifacts/
51 | **/Properties/launchSettings.json
52 |
53 | *_i.c
54 | *_p.c
55 | *_i.h
56 | *.ilk
57 | *.meta
58 | *.obj
59 | *.pch
60 | *.pdb
61 | *.pgc
62 | *.pgd
63 | *.rsp
64 | *.sbr
65 | *.tlb
66 | *.tli
67 | *.tlh
68 | *.tmp
69 | *.tmp_proj
70 | *.log
71 | *.vspscc
72 | *.vssscc
73 | .builds
74 | *.pidb
75 | *.svclog
76 | *.scc
77 |
78 | # Chutzpah Test files
79 | _Chutzpah*
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opendb
86 | *.opensdf
87 | *.sdf
88 | *.cachefile
89 | *.VC.db
90 | *.VC.VC.opendb
91 |
92 | # Visual Studio profiler
93 | *.psess
94 | *.vsp
95 | *.vspx
96 | *.sap
97 |
98 | # TFS 2012 Local Workspace
99 | $tf/
100 |
101 | # Guidance Automation Toolkit
102 | *.gpState
103 |
104 | # ReSharper is a .NET coding add-in
105 | _ReSharper*/
106 | *.[Rr]e[Ss]harper
107 | *.DotSettings.user
108 |
109 | # JustCode is a .NET coding add-in
110 | .JustCode
111 |
112 | # TeamCity is a build add-in
113 | _TeamCity*
114 |
115 | # DotCover is a Code Coverage Tool
116 | *.dotCover
117 |
118 | # Visual Studio code coverage results
119 | *.coverage
120 | *.coveragexml
121 |
122 | # NCrunch
123 | _NCrunch_*
124 | .*crunch*.local.xml
125 | nCrunchTemp_*
126 |
127 | # MightyMoose
128 | *.mm.*
129 | AutoTest.Net/
130 |
131 | # Web workbench (sass)
132 | .sass-cache/
133 |
134 | # Installshield output folder
135 | [Ee]xpress/
136 |
137 | # DocProject is a documentation generator add-in
138 | DocProject/buildhelp/
139 | DocProject/Help/*.HxT
140 | DocProject/Help/*.HxC
141 | DocProject/Help/*.hhc
142 | DocProject/Help/*.hhk
143 | DocProject/Help/*.hhp
144 | DocProject/Help/Html2
145 | DocProject/Help/html
146 |
147 | # Click-Once directory
148 | publish/
149 |
150 | # Publish Web Output
151 | *.[Pp]ublish.xml
152 | *.azurePubxml
153 | # TODO: Comment the next line if you want to checkin your web deploy settings
154 | # but database connection strings (with potential passwords) will be unencrypted
155 | *.pubxml
156 | *.publishproj
157 |
158 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
159 | # checkin your Azure Web App publish settings, but sensitive information contained
160 | # in these scripts will be unencrypted
161 | PublishScripts/
162 |
163 | # NuGet Packages
164 | *.nupkg
165 | # The packages folder can be ignored because of Package Restore
166 | **/packages/*
167 | # except build/, which is used as an MSBuild target.
168 | !**/packages/build/
169 | # Uncomment if necessary however generally it will be regenerated when needed
170 | #!**/packages/repositories.config
171 | # NuGet v3's project.json files produces more ignorable files
172 | *.nuget.props
173 | *.nuget.targets
174 |
175 | # Microsoft Azure Build Output
176 | csx/
177 | *.build.csdef
178 |
179 | # Microsoft Azure Emulator
180 | ecf/
181 | rcf/
182 |
183 | # Windows Store app package directories and files
184 | AppPackages/
185 | BundleArtifacts/
186 | Package.StoreAssociation.xml
187 | _pkginfo.txt
188 |
189 | # Visual Studio cache files
190 | # files ending in .cache can be ignored
191 | *.[Cc]ache
192 | # but keep track of directories ending in .cache
193 | !*.[Cc]ache/
194 |
195 | # Others
196 | ClientBin/
197 | ~$*
198 | *~
199 | *.dbmdl
200 | *.dbproj.schemaview
201 | *.jfm
202 | *.pfx
203 | *.publishsettings
204 | orleans.codegen.cs
205 |
206 | # Since there are multiple workflows, uncomment next line to ignore bower_components
207 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
208 | #bower_components/
209 |
210 | # RIA/Silverlight projects
211 | Generated_Code/
212 |
213 | # Backup & report files from converting an old project file
214 | # to a newer Visual Studio version. Backup files are not needed,
215 | # because we have git ;-)
216 | _UpgradeReport_Files/
217 | Backup*/
218 | UpgradeLog*.XML
219 | UpgradeLog*.htm
220 |
221 | # SQL Server files
222 | *.mdf
223 | *.ldf
224 | *.ndf
225 |
226 | # Business Intelligence projects
227 | *.rdl.data
228 | *.bim.layout
229 | *.bim_*.settings
230 |
231 | # Microsoft Fakes
232 | FakesAssemblies/
233 |
234 | # GhostDoc plugin setting file
235 | *.GhostDoc.xml
236 |
237 | # Node.js Tools for Visual Studio
238 | .ntvs_analysis.dat
239 | node_modules/
240 |
241 | # Typescript v1 declaration files
242 | typings/
243 |
244 | # Visual Studio 6 build log
245 | *.plg
246 |
247 | # Visual Studio 6 workspace options file
248 | *.opt
249 |
250 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
251 | *.vbw
252 |
253 | # Visual Studio LightSwitch build output
254 | **/*.HTMLClient/GeneratedArtifacts
255 | **/*.DesktopClient/GeneratedArtifacts
256 | **/*.DesktopClient/ModelManifest.xml
257 | **/*.Server/GeneratedArtifacts
258 | **/*.Server/ModelManifest.xml
259 | _Pvt_Extensions
260 |
261 | # Paket dependency manager
262 | .paket/paket.exe
263 | paket-files/
264 |
265 | # FAKE - F# Make
266 | .fake/
267 |
268 | # JetBrains Rider
269 | .idea/
270 | *.sln.iml
271 |
272 | # CodeRush
273 | .cr/
274 |
275 | # Python Tools for Visual Studio (PTVS)
276 | __pycache__/
277 | *.pyc
278 |
279 | # Cake - Uncomment if you are using it
280 | # tools/**
281 | # !tools/packages.config
282 |
283 | # Telerik's JustMock configuration file
284 | *.jmconfig
285 |
286 | # BizTalk build output
287 | *.btp.cs
288 | *.btm.cs
289 | *.odx.cs
290 | *.xsd.cs
291 |
--------------------------------------------------------------------------------
/BuildConsole/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/BuildConsole/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/BuildConsole/App.ico
--------------------------------------------------------------------------------
/BuildConsole/BuildConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}
8 | Exe
9 | Properties
10 | BuildConsole
11 | BuildConsole
12 | bin\DebugRelease\
13 | v4.5.2
14 | 512
15 | true
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 | App.ico
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
65 |
--------------------------------------------------------------------------------
/BuildConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace BuildConsole {
12 | /**The main program.*/
13 | class Program {
14 | //========== CONSTANTS ===========
15 | #region Constants
16 |
17 | /**The path of the temporary folder.*/
18 | private static readonly string TempDirectory = Path.Combine(Path.GetTempPath(), "TriggersToolsGames", "QuickWaveBank");
19 | /**The path of the temporary XactBld3 executable.*/
20 | private static readonly string TempXactBld = Path.Combine(TempDirectory, "XactBld3.exe");
21 | /**The path of the temporary BuildConsole executable.*/
22 | private static readonly string TempBuildConsole = Path.Combine(TempDirectory, "BuildConsole.exe");
23 | /**The path of the temporary Xap project file.*/
24 | private static readonly string TempProjectFile = Path.Combine(TempDirectory, "WaveBankProject.xap");
25 | /**The path of the temporary created wave bank.*/
26 | private static readonly string TempWaveBank = Path.Combine(TempDirectory, "Wave Bank.xwb");
27 | /**The path of the temporary created wave bank.*/
28 | private const int CancelExitCode = -1073741510;
29 | /**The path of the temporary created wave bank.*/
30 | private const int FailedExitCode = -100;
31 |
32 | #endregion
33 | //========= ENTRY POINT ==========
34 | #region Entry Point
35 |
36 | /**The entry point of the program.*/
37 | static int Main(string[] args) {
38 | Environment.ExitCode = CancelExitCode;
39 |
40 | Console.Title = "Wave Bank Builder (XactBld3)";
41 | Console.WriteLine("Building Wave Bank...");
42 |
43 | DateTime lastModified = (File.Exists(TempWaveBank) ?
44 | File.GetLastWriteTime(TempWaveBank) :
45 | DateTime.Now
46 | );
47 |
48 | ProcessStartInfo start = new ProcessStartInfo();
49 | start.FileName = TempXactBld;
50 | start.Arguments = "/X:REPORT /X:HEADER /X:SOUNDBANK /X:CUELIST /WIN32 /F " +
51 | "\"" + Path.GetFileName(TempProjectFile) + "\""; //TODO: fix later with a proper constant (needed to avoid special characters in usernames)
52 | start.UseShellExecute = false;
53 | start.WorkingDirectory = TempDirectory;
54 | Process process = Process.Start(start);
55 | process.WaitForExit();
56 |
57 | if (process.ExitCode != 0 || !File.Exists(TempWaveBank) || File.GetLastWriteTime(TempWaveBank) <= lastModified) {
58 | Environment.ExitCode = FailedExitCode;
59 |
60 | // Sleep now so the window is not hidden afterwards by QuickWaveBanks's hide log.
61 | Thread.Sleep(200);
62 | // Just in case the window is currently hidden.
63 | ShowWindow();
64 |
65 | Console.ForegroundColor = ConsoleColor.Red;
66 | Console.WriteLine("Failed to create wave bank!");
67 | Console.WriteLine(" See console log for more details.");
68 | Console.ForegroundColor = ConsoleColor.Gray;
69 | Console.WriteLine();
70 | Console.WriteLine("Press any key to close...");
71 |
72 | Console.Read();
73 | }
74 | else {
75 | Environment.ExitCode = 0;
76 | }
77 | return Environment.ExitCode;
78 | }
79 |
80 | #endregion
81 | //========= DLL IMPORTS ==========
82 | #region Dll Imports
83 |
84 | private static void ShowWindow() {
85 | ShowWindow(GetConsoleWindow(), SW_RESTORE);
86 | }
87 |
88 | [DllImport("user32.dll")]
89 | private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
90 | [DllImport("kernel32.dll")]
91 | private static extern IntPtr GetConsoleWindow();
92 |
93 | private const int SW_RESTORE = 9;
94 |
95 | #endregion
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/BuildConsole/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("BuildConsole")]
10 | [assembly: AssemblyDescription("BuildConsole - Used to build Wave Banks with XactBld3")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("BuildConsole")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 | [assembly: Guid("8157C984-9D17-47BC-9336-5A4C3A2E4871")]
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | // You can specify all the values or you can default the Build and Revision Numbers
34 | // by using the '*' as shown below:
35 | // [assembly: AssemblyVersion("1.0.*")]
36 | [assembly: AssemblyVersion("1.0.3.0")]
37 | [assembly: AssemblyFileVersion("1.0.3.0")]
38 | [assembly: NeutralResourcesLanguage("en-US")]
39 |
40 |
--------------------------------------------------------------------------------
/License:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Robert Jordan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/QuickWaveBank.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickWaveBank", "QuickWaveBank\QuickWaveBank.csproj", "{B550B2E1-A47D-454C-96D9-F85A8980D8FF}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildConsole", "BuildConsole\BuildConsole.csproj", "{77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {B550B2E1-A47D-454C-96D9-F85A8980D8FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {B550B2E1-A47D-454C-96D9-F85A8980D8FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {B550B2E1-A47D-454C-96D9-F85A8980D8FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {B550B2E1-A47D-454C-96D9-F85A8980D8FF}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}.Debug|Any CPU.ActiveCfg = Release|Any CPU
21 | {77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}.Debug|Any CPU.Build.0 = Release|Any CPU
22 | {77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {77DC12FA-D6FA-4A42-912E-0D8E7E4AA83F}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/QuickWaveBank/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | True
21 |
22 |
23 | False
24 |
25 |
26 | True
27 |
28 |
29 | False
30 |
31 |
32 | xWMA
33 |
34 |
35 | 60
36 |
37 |
38 | 128
39 |
40 |
41 | 0.5
42 |
43 |
44 | False
45 |
46 |
47 | Ask
48 |
49 |
50 |
51 |
52 |
53 | True
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/QuickWaveBank/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/App.ico
--------------------------------------------------------------------------------
/QuickWaveBank/App.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/QuickWaveBank/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Diagnostics;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Runtime.InteropServices;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 | using System.Windows;
12 | using System.Windows.Threading;
13 | using QuickWaveBank.Windows;
14 | using QuickWaveBank.Util;
15 | using System.Globalization;
16 | using System.IO;
17 |
18 | namespace QuickWaveBank {
19 | /**The WPF application.*/
20 | public partial class App : Application {
21 | //=========== MEMBERS ============
22 | #region Members
23 |
24 | /**Needs to be out here otherwise it can't server its purpose.*/
25 | private Mutex m;
26 | /**The last exception. Used to prevent multiple error windows for the same error.*/
27 | private static object lastException = null;
28 |
29 | #endregion
30 | //========= CONSTRUCTORS =========
31 | #region Constructors
32 |
33 | /**Constructs the WPF app.*/
34 | public App() {
35 | // Setup embedded assembly resolving
36 | AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssemblies;
37 |
38 | // We only want to run one instance at a time. Otherwise the temporary
39 | // output files will be modified by two or more programs.
40 | bool isNew;
41 | m = new Mutex(true, "Global\\" + GUID, out isNew);
42 | if (!isNew) {
43 | TriggerMessageBox.Show(null, MessageIcon.Warning, "Quick Wave Bank is already running. Cannot run more than one instance at the same time.", "Already Running");
44 | Environment.Exit(0);
45 | }
46 | }
47 |
48 | #endregion
49 | //============ EVENTS ============
50 | #region Events
51 |
52 | private Assembly OnResolveAssemblies(object sender, ResolveEventArgs args) {
53 | var executingAssembly = Assembly.GetExecutingAssembly();
54 | var assemblyName = new AssemblyName(args.Name);
55 |
56 | string path = assemblyName.Name + ".dll";
57 | if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false) {
58 | path = string.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
59 | }
60 |
61 | using (Stream stream = executingAssembly.GetManifestResourceStream(path)) {
62 | if (stream == null)
63 | return null;
64 |
65 | byte[] assemblyRawBytes = new byte[stream.Length];
66 | stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
67 | return Assembly.Load(assemblyRawBytes);
68 | }
69 | }
70 | private void OnAppStartup(object sender, StartupEventArgs e) {
71 | // Catch exceptions not in a UI thread
72 | AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnAppDomainUnhandledException);
73 | TaskScheduler.UnobservedTaskException += OnTaskSchedulerUnobservedTaskException;
74 | }
75 | private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
76 | if (e.Exception != lastException) {
77 | lastException = e.Exception;
78 | if (ErrorMessageBox.Show(e.Exception))
79 | Environment.Exit(0);
80 | e.Handled = true;
81 | }
82 | }
83 | private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) {
84 | if (e.ExceptionObject != lastException) {
85 | lastException = e.ExceptionObject;
86 | Dispatcher.Invoke(() => {
87 | if (ErrorMessageBox.Show(e.ExceptionObject))
88 | Environment.Exit(0);
89 | });
90 | }
91 | }
92 | private void OnTaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
93 | if (e.Exception != lastException) {
94 | lastException = e.Exception;
95 | Dispatcher.Invoke(() => {
96 | if (ErrorMessageBox.Show(e.Exception))
97 | Environment.Exit(0);
98 | });
99 | }
100 | }
101 |
102 | #endregion
103 | //=========== HELPERS ============
104 | #region Helpers
105 |
106 | /**Gets the GUID of the application.*/
107 | private static string GUID {
108 | get {
109 | object[] assemblyObjects =
110 | Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), true);
111 |
112 | if (assemblyObjects.Length > 0) {
113 | return new Guid(((GuidAttribute)assemblyObjects[0]).Value).ToString();
114 | }
115 | return "";
116 | }
117 | }
118 |
119 | #endregion
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/QuickWaveBank/Commands.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows.Input;
7 |
8 | namespace QuickWaveBank {
9 | public static class Commands {
10 | public static readonly RoutedUICommand MySaveAs = new RoutedUICommand(
11 | "Save List As", "MySaveAs", typeof(Commands),
12 | new InputGestureCollection() { new KeyGesture(Key.S, ModifierKeys.Control | ModifierKeys.Shift) }
13 | );
14 | public static readonly RoutedUICommand Exit = new RoutedUICommand(
15 | "Exit", "Exit", typeof(Commands),
16 | new InputGestureCollection() { new KeyGesture(Key.W, ModifierKeys.Control) }
17 | );
18 | public static readonly RoutedUICommand Build = new RoutedUICommand(
19 | "Build Wave Bank", "Build", typeof(Commands),
20 | new InputGestureCollection() { new KeyGesture(Key.F5) }
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/QuickWaveBank/Config.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using QuickWaveBank.Properties;
9 |
10 | namespace QuickWaveBank {
11 | /**The different types of compression formats.*/
12 | public enum CompressionFormats {
13 | PCM = 0,
14 | ADPCM = 2,
15 | xWMA = 353
16 | }
17 | /**The available samples per block of the ADPCM format.*/
18 | public enum ADPCMSamplesPerBlock {
19 | S32 = 32,
20 | S64 = 64,
21 | S128 = 128,
22 | S256 = 256,
23 | S512 = 512
24 | }
25 | /**How to interact with the user when an audio file needs converting.*/
26 | [Flags]
27 | public enum ConvertOptions {
28 | // Full Flags
29 | Ask = 0x0,
30 | Auto = 0x3,
31 | WaitTillBuild = 0x4,
32 |
33 | // Flags
34 | AskConvert = 0x0,
35 | AskOverwrite = 0x0,
36 | AutoConvert = 0x1,
37 | AutoOverwrite = 0x2
38 | }
39 |
40 | /**The config settings handler.*/
41 | public static class Config {
42 | //=========== MEMBERS ============
43 | #region Members
44 |
45 | // General
46 | /**The output wave bank file.*/
47 | public static string OutputFile { get; set; }
48 | /**True if drag and drop is enabled.*/
49 | public static bool DragAndDrop { get; set; } = true;
50 | /**True if the console log is shown by default when building.*/
51 | public static bool ShowLog { get; set; } = false;
52 | /**True if track names are shown next to each wave entry.*/
53 | public static bool TrackNames { get; set; } = true;
54 | /**The current volume.*/
55 | public static double Volume { get; set; } = 0.5;
56 | /**True if the volume is muted.*/
57 | public static bool Muted { get; set; } = false;
58 | /**How file conversion is handled.*/
59 | public static ConvertOptions ConvertOption { get; set; } = ConvertOptions.Ask;
60 | /**The last visited directory of the folder browser.*/
61 | public static string LastFolderBrowser { get; set; }
62 | /**True if quick wave bank asks to save the track list on closing.*/
63 | public static bool SaveConfirmation { get; set; } = true;
64 |
65 | // Advanced
66 | /**True if the wave bank is a streaming wave bank.*/
67 | public static bool Streaming { get; set; } = false;
68 | /**The format of the wave bank compression.*/
69 | public static CompressionFormats Format { get; set; } = CompressionFormats.xWMA;
70 | /**The quality of the xWMA format [1, 100].*/
71 | public static int WMAQuality { get; set; } = 60;
72 | /**The samples per block of the ADPCM format.*/
73 | public static ADPCMSamplesPerBlock SamplesPerBlock { get; set; } = ADPCMSamplesPerBlock.S128;
74 |
75 | #endregion
76 | //=========== LOADING ============
77 | #region Loading
78 |
79 | /**Loads the settings.*/
80 | public static void Load() {
81 | // General
82 | OutputFile = Settings.Default.OutputFile;
83 | DragAndDrop = Settings.Default.DragAndDrop;
84 | ShowLog = Settings.Default.ShowLog;
85 | TrackNames = Settings.Default.TrackNames;
86 | Volume = Settings.Default.Volume;
87 | Muted = Settings.Default.Muted;
88 | LastFolderBrowser = Settings.Default.LastFolderBrowser;
89 | SaveConfirmation = Settings.Default.SaveConfirmation;
90 | if (string.IsNullOrEmpty(LastFolderBrowser)) {
91 | LastFolderBrowser = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
92 | }
93 | ConvertOptions convertOption;
94 | if (Enum.TryParse(Settings.Default.ConvertOption, out convertOption))
95 | ConvertOption = convertOption;
96 | else
97 | ConvertOption = ConvertOptions.Ask;
98 |
99 | if (string.IsNullOrEmpty(OutputFile))
100 | OutputFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Wave Bank.xwb");
101 |
102 | // Advanced
103 | Streaming = Settings.Default.Streaming;
104 | WMAQuality = Settings.Default.WMAQuality;
105 | SamplesPerBlock = (ADPCMSamplesPerBlock)Settings.Default.ADPCMSamplesPerBlock;
106 | CompressionFormats format;
107 | if (Enum.TryParse(Settings.Default.Format, out format))
108 | Format = format;
109 | else
110 | Format = CompressionFormats.xWMA;
111 |
112 | }
113 | /**Saves the settings.*/
114 | public static void Save() {
115 | // General
116 | Settings.Default.OutputFile = OutputFile;
117 | Settings.Default.DragAndDrop = DragAndDrop;
118 | Settings.Default.ShowLog = ShowLog;
119 | Settings.Default.TrackNames = TrackNames;
120 | Settings.Default.Volume = Volume;
121 | Settings.Default.Muted = Muted;
122 | Settings.Default.ConvertOption = ConvertOption.ToString();
123 | Settings.Default.LastFolderBrowser = LastFolderBrowser;
124 | Settings.Default.SaveConfirmation = SaveConfirmation;
125 |
126 | // Advanced
127 | Settings.Default.Streaming = Streaming;
128 | Settings.Default.Format = Format.ToString();
129 | Settings.Default.WMAQuality = WMAQuality;
130 | Settings.Default.ADPCMSamplesPerBlock = (int)SamplesPerBlock;
131 |
132 | Settings.Default.Save();
133 | }
134 |
135 | #endregion
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/QuickWaveBank/Controls/IntSpinner.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/QuickWaveBank/Controls/IntSpinner.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Controls.Primitives;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 | using Xceed.Wpf.Toolkit;
17 |
18 | namespace QuickWaveBank.Controls {
19 | /**Signifies an numeric value change.*/
20 | public class ValueChangedEventArgs : RoutedEventArgs {
21 | //=========== MEMBERS ============
22 | #region Members
23 |
24 | /**The previous value.*/
25 | public T Previous;
26 | /**The new value.*/
27 | public T New;
28 |
29 | #endregion
30 | //========= CONSTRUCTORS =========
31 | #region Constructors
32 |
33 | /**Constructs the value change event args.*/
34 | public ValueChangedEventArgs(RoutedEvent routedEvent, T previousValue, T newValue) : base(routedEvent) {
35 | Previous = previousValue;
36 | New = newValue;
37 | }
38 |
39 | #endregion
40 | }
41 |
42 | /**An integer-based numeric spinner.*/
43 | public partial class IntSpinner : UserControl {
44 | //=========== MEMBERS ============
45 | #region Members
46 |
47 | /**The value used when a number can't be parsed.*/
48 | private int errorValue = 0;
49 | /**The current value.*/
50 | private int number = 1;
51 | /**The maximum value.*/
52 | private int maximum = int.MaxValue;
53 | /**The minimum value.*/
54 | private int minimum = int.MinValue;
55 | /**The spinner increments.*/
56 | private int increment = 1;
57 |
58 | #endregion
59 | //========= CONSTRUCTORS =========
60 | #region Constructors
61 |
62 | /**Constructs the numeric spinner.*/
63 | public IntSpinner() {
64 | InitializeComponent();
65 |
66 | UpdateSpinner();
67 | UpdateTextBox();
68 | }
69 |
70 | #endregion
71 | //============ EVENTS ============
72 | #region Events
73 |
74 | /**Event handler for value change events.*/
75 | public delegate void IntChangedEventHandler(object sender, ValueChangedEventArgs e);
76 | /**The value changed routed event.*/
77 | public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(IntChangedEventHandler), typeof(IntSpinner));
78 | /**Called when the value has been changed.*/
79 | public event IntChangedEventHandler ValueChanged {
80 | add { AddHandler(ValueChangedEvent, value); }
81 | remove { RemoveHandler(ValueChangedEvent, value); }
82 | }
83 |
84 | #endregion
85 | //========== PROPERTIES ==========
86 | #region Properties
87 |
88 | /**The value used when a number can't be parsed.*/
89 | public int ErrorValue {
90 | get { return errorValue; }
91 | set {
92 | if (value < minimum || value > maximum)
93 | throw new IndexOutOfRangeException("NumericSpinner ErrorValue outside of Minimum or Maximum range.");
94 | errorValue = value;
95 | }
96 | }
97 | /**The current value.*/
98 | public int Value {
99 | get { return number; }
100 | set {
101 | if (value < minimum || value > maximum)
102 | throw new IndexOutOfRangeException("NumericSpinner Value outside of Minimum or Maximum range.");
103 | if (number != value) {
104 | int oldValue = number;
105 | number = value;
106 | UpdateSpinner();
107 | UpdateTextBox();
108 | RaiseEvent(new ValueChangedEventArgs(IntSpinner.ValueChangedEvent, oldValue, number));
109 | }
110 | }
111 | }
112 | /**The maximum value.*/
113 | public int Maximum {
114 | get { return maximum; }
115 | set {
116 | if (value < minimum)
117 | throw new IndexOutOfRangeException("NumericSpinner Maximum is less than Minimum range.");
118 | maximum = value;
119 | if (number > maximum)
120 | Value = maximum;
121 | else
122 | UpdateSpinner();
123 | if (errorValue > maximum)
124 | errorValue = maximum;
125 | }
126 | }
127 | /**The minimum value.*/
128 | public int Minimum {
129 | get { return minimum; }
130 | set {
131 | if (value > maximum)
132 | throw new IndexOutOfRangeException("NumericSpinner Minimum is greater than Maximum range.");
133 | minimum = value;
134 | if (number < minimum)
135 | Value = minimum;
136 | else
137 | UpdateSpinner();
138 | if (errorValue < minimum)
139 | errorValue = minimum;
140 | }
141 | }
142 | /**The up/down increments.*/
143 | public int Increment {
144 | get { return increment; }
145 | set { increment = value; }
146 | }
147 | /**The text in the text box.*/
148 | public string Text {
149 | get { return textBox.Text; }
150 | }
151 |
152 | #endregion
153 | //=========== EDITING ============
154 | #region Editing
155 |
156 | /**Selects everything in the spinner.*/
157 | public void SelectAll() {
158 | textBox.Focusable = true;
159 | textBox.Focus();
160 | textBox.SelectAll();
161 | }
162 |
163 | #endregion
164 | //=========== HELPERS ============
165 | #region Helpers
166 |
167 | /**Updates the state of the spinner.*/
168 | private void UpdateSpinner() {
169 | spinner.ValidSpinDirection = ValidSpinDirections.None;
170 | spinner.ValidSpinDirection |= (number != maximum ? ValidSpinDirections.Increase : ValidSpinDirections.None);
171 | spinner.ValidSpinDirection |= (number != minimum ? ValidSpinDirections.Decrease : ValidSpinDirections.None);
172 | }
173 | /**Updates the state of the textbox.*/
174 | private void UpdateTextBox() {
175 | int caretIndex = textBox.CaretIndex;
176 | textBox.Text = number.ToString();
177 | textBox.CaretIndex = Math.Min(textBox.Text.Length, caretIndex);
178 | UpdateTextBoxError();
179 | }
180 | /**Updates the state of the textbox.*/
181 | private void UpdateTextBox(string newText, int newCaretIndex) {
182 | int caretIndex = textBox.CaretIndex;
183 | textBox.Text = newText;
184 | textBox.CaretIndex = Math.Min(textBox.Text.Length, newCaretIndex);
185 | UpdateTextBoxError();
186 | }
187 | /**Updates the error state of the textbox.*/
188 | private void UpdateTextBoxError() {
189 | bool error = false;
190 | try {
191 | int newNum = int.Parse(Text);
192 | if (newNum > maximum || newNum < minimum) {
193 | error = true;
194 | }
195 | }
196 | catch (OverflowException) {
197 | error = true;
198 | }
199 | catch (FormatException) {
200 | error = true;
201 | }
202 | if (error)
203 | textBox.Foreground = new SolidColorBrush(Color.FromRgb(220, 0, 0));
204 | else
205 | textBox.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
206 | }
207 |
208 | #endregion
209 | //============ EVENTS ============
210 | #region Events
211 |
212 | private void OnTextInput(object sender, TextCompositionEventArgs e) {
213 | int oldValue = number;
214 | TextBox textBox = sender as TextBox;
215 | e.Handled = true;
216 | bool invalidChar = false;
217 | for (int i = 0; i < e.Text.Length && !invalidChar; i++) {
218 | if ((e.Text[i] < '0' || e.Text[i] > '9') && (e.Text[i] != '-' || textBox.CaretIndex != 0 || i > 0 || minimum >= 0))
219 | invalidChar = true;
220 | }
221 | if (!invalidChar) {
222 | string newText = "";
223 | if (textBox.SelectionLength != 0)
224 | newText = textBox.Text.Remove(textBox.SelectionStart, textBox.SelectionLength).Insert(textBox.SelectionStart, e.Text);
225 | else
226 | newText = textBox.Text.Insert(textBox.SelectionStart, e.Text);
227 | try {
228 | number = int.Parse(newText);
229 | if (number > maximum) {
230 | number = maximum;
231 | UpdateTextBox();
232 | textBox.CaretIndex += e.Text.Length;
233 | }
234 | else if (number < minimum) {
235 | number = minimum;
236 | UpdateTextBox(newText, textBox.CaretIndex + e.Text.Length);
237 | }
238 | else {
239 | UpdateTextBox(newText, textBox.CaretIndex + e.Text.Length);
240 | }
241 | }
242 | catch (OverflowException) {
243 | if (textBox.Text.Length > 0 && textBox.Text[0] == '-') {
244 | //Underflow
245 | number = minimum;
246 | UpdateTextBox();
247 | textBox.CaretIndex = textBox.Text.Length;
248 | }
249 | else {
250 | number = maximum;
251 | UpdateTextBox();
252 | textBox.CaretIndex = textBox.Text.Length;
253 | }
254 | }
255 | catch (FormatException) {
256 | if (newText == "-" || newText == "") {
257 | // Don't worry, the user is just writing a negative number or typing a new number
258 | number = errorValue;
259 | UpdateTextBox(newText, textBox.CaretIndex + e.Text.Length);
260 | }
261 | else {
262 | // Shouldn't happen?
263 | number = errorValue;
264 | UpdateTextBox();
265 | textBox.CaretIndex = textBox.Text.Length;
266 | }
267 | }
268 | if (number != oldValue) {
269 | UpdateSpinner();
270 | RaiseEvent(new ValueChangedEventArgs(IntSpinner.ValueChangedEvent, oldValue, number));
271 | }
272 | }
273 | UpdateTextBoxError();
274 | }
275 | private void OnTextChanged(object sender, TextChangedEventArgs e) {
276 | int oldValue = number;
277 | try {
278 | number = int.Parse(textBox.Text);
279 | if (number > maximum) {
280 | number = maximum;
281 | UpdateTextBox();
282 | textBox.CaretIndex = textBox.Text.Length;
283 | }
284 | else if (number < minimum) {
285 | number = minimum;
286 | }
287 | }
288 | catch (OverflowException) {
289 | if (textBox.Text.Length > 0 && textBox.Text[0] == '-') {
290 | //Underflow
291 | number = minimum;
292 | UpdateTextBox();
293 | textBox.CaretIndex = textBox.Text.Length;
294 | }
295 | else {
296 | number = maximum;
297 | UpdateTextBox();
298 | textBox.CaretIndex = textBox.Text.Length;
299 | }
300 | }
301 | catch (FormatException) {
302 | if (textBox.Text == "-" || textBox.Text == "") {
303 | // Don't worry, the user is just writing a negative number or typing a new number
304 | number = errorValue;
305 | }
306 | else {
307 | number = errorValue;
308 | UpdateTextBox();
309 | textBox.CaretIndex = textBox.Text.Length;
310 | }
311 | }
312 | if (number != oldValue) {
313 | UpdateSpinner();
314 | RaiseEvent(new ValueChangedEventArgs(IntSpinner.ValueChangedEvent, oldValue, number));
315 | }
316 |
317 | UpdateTextBoxError();
318 | }
319 | private void OnSpinnerSpin(object sender, SpinEventArgs e) {
320 | int oldValue = number;
321 | if (e.Direction == SpinDirection.Increase)
322 | number = Math.Min(maximum, number + increment);
323 | else if (e.Direction == SpinDirection.Decrease)
324 | number = Math.Max(minimum, number - increment);
325 | if (number != oldValue) {
326 | UpdateSpinner();
327 | UpdateTextBox();
328 | textBox.CaretIndex = textBox.Text.Length;
329 | RaiseEvent(new ValueChangedEventArgs(IntSpinner.ValueChangedEvent, oldValue, number));
330 | }
331 | }
332 | private void OnGotFocus(object sender, RoutedEventArgs e) {
333 | this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
334 | }
335 | private void OnFocusLost(object sender, RoutedEventArgs e) {
336 | UpdateTextBox();
337 | }
338 |
339 | #endregion
340 | }
341 | }
342 |
--------------------------------------------------------------------------------
/QuickWaveBank/DragAndDrop/DragAdorner.cs:
--------------------------------------------------------------------------------
1 | // Copyright (C) Josh Smith - January 2007
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Windows.Documents;
6 | using System.Windows;
7 | using System.Windows.Media;
8 | using System.Windows.Shapes;
9 | using System.Windows.Media.Animation;
10 | using System.Windows.Controls;
11 |
12 | namespace WPF.JoshSmith.Adorners
13 | {
14 | ///
15 | /// Renders a visual which can follow the mouse cursor,
16 | /// such as during a drag-and-drop operation.
17 | ///
18 | public class DragAdorner : Adorner
19 | {
20 | #region Data
21 |
22 | private Rectangle child = null;
23 | private double offsetLeft = 0;
24 | private double offsetTop = 0;
25 |
26 | #endregion // Data
27 |
28 | #region Constructor
29 |
30 | ///
31 | /// Initializes a new instance of DragVisualAdorner.
32 | ///
33 | /// The element being adorned.
34 | /// The size of the adorner.
35 | /// A brush to with which to paint the adorner.
36 | public DragAdorner( UIElement adornedElement, Size size, Brush brush )
37 | : base( adornedElement )
38 | {
39 | Rectangle rect = new Rectangle();
40 | rect.Fill = brush;
41 | rect.Width = size.Width;
42 | rect.Height = size.Height;
43 | rect.IsHitTestVisible = false;
44 | this.child = rect;
45 | }
46 |
47 | #endregion // Constructor
48 |
49 | #region Public Interface
50 |
51 | #region GetDesiredTransform
52 |
53 | ///
54 | /// Override.
55 | ///
56 | ///
57 | ///
58 | public override GeneralTransform GetDesiredTransform( GeneralTransform transform )
59 | {
60 | GeneralTransformGroup result = new GeneralTransformGroup();
61 | result.Children.Add( base.GetDesiredTransform( transform ) );
62 | result.Children.Add( new TranslateTransform( this.offsetLeft, this.offsetTop ) );
63 | return result;
64 | }
65 |
66 | #endregion // GetDesiredTransform
67 |
68 | #region OffsetLeft
69 |
70 | ///
71 | /// Gets/sets the horizontal offset of the adorner.
72 | ///
73 | public double OffsetLeft
74 | {
75 | get { return this.offsetLeft; }
76 | set
77 | {
78 | this.offsetLeft = value;
79 | UpdateLocation();
80 | }
81 | }
82 |
83 | #endregion // OffsetLeft
84 |
85 | #region SetOffsets
86 |
87 | ///
88 | /// Updates the location of the adorner in one atomic operation.
89 | ///
90 | ///
91 | ///
92 | public void SetOffsets( double left, double top )
93 | {
94 | this.offsetLeft = left;
95 | this.offsetTop = top;
96 | this.UpdateLocation();
97 | }
98 |
99 | #endregion // SetOffsets
100 |
101 | #region OffsetTop
102 |
103 | ///
104 | /// Gets/sets the vertical offset of the adorner.
105 | ///
106 | public double OffsetTop
107 | {
108 | get { return this.offsetTop; }
109 | set
110 | {
111 | this.offsetTop = value;
112 | UpdateLocation();
113 | }
114 | }
115 |
116 | #endregion // OffsetTop
117 |
118 | #endregion // Public Interface
119 |
120 | #region Protected Overrides
121 |
122 | ///
123 | /// Override.
124 | ///
125 | ///
126 | ///
127 | protected override Size MeasureOverride( Size constraint )
128 | {
129 | this.child.Measure( constraint );
130 | return this.child.DesiredSize;
131 | }
132 |
133 | ///
134 | /// Override.
135 | ///
136 | ///
137 | ///
138 | protected override Size ArrangeOverride( Size finalSize )
139 | {
140 | this.child.Arrange( new Rect( finalSize ) );
141 | return finalSize;
142 | }
143 |
144 | ///
145 | /// Override.
146 | ///
147 | ///
148 | ///
149 | protected override Visual GetVisualChild( int index )
150 | {
151 | return this.child;
152 | }
153 |
154 | ///
155 | /// Override. Always returns 1.
156 | ///
157 | protected override int VisualChildrenCount
158 | {
159 | get { return 1; }
160 | }
161 |
162 | #endregion // Protected Overrides
163 |
164 | #region Private Helpers
165 |
166 | private void UpdateLocation()
167 | {
168 | AdornerLayer adornerLayer = this.Parent as AdornerLayer;
169 | if( adornerLayer != null )
170 | adornerLayer.Update( this.AdornedElement );
171 | }
172 |
173 | #endregion // Private Helpers
174 | }
175 | }
--------------------------------------------------------------------------------
/QuickWaveBank/DragAndDrop/MouseUtilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 | using System.Windows.Media;
7 |
8 | namespace WPF.JoshSmith.Controls.Utilities
9 | {
10 | ///
11 | /// Provides access to the mouse location by calling unmanaged code.
12 | ///
13 | ///
14 | /// This class was written by Dan Crevier (Microsoft).
15 | /// http://blogs.msdn.com/llobo/archive/2006/09/06/Scrolling-Scrollviewer-on-Mouse-Drag-at-the-boundaries.aspx
16 | ///
17 | public class MouseUtilities
18 | {
19 | [StructLayout( LayoutKind.Sequential )]
20 | private struct Win32Point
21 | {
22 | public Int32 X;
23 | public Int32 Y;
24 | };
25 |
26 | [DllImport( "user32.dll" )]
27 | private static extern bool GetCursorPos( ref Win32Point pt );
28 |
29 | [DllImport( "user32.dll" )]
30 | private static extern bool ScreenToClient( IntPtr hwnd, ref Win32Point pt );
31 |
32 | ///
33 | /// Returns the mouse cursor location. This method is necessary during
34 | /// a drag-drop operation because the WPF mechanisms for retrieving the
35 | /// cursor coordinates are unreliable.
36 | ///
37 | /// The Visual to which the mouse coordinates will be relative.
38 | public static Point GetMousePosition( Visual relativeTo )
39 | {
40 | Win32Point mouse = new Win32Point();
41 | GetCursorPos( ref mouse );
42 |
43 | // Using PointFromScreen instead of Dan Crevier's code (commented out below)
44 | // is a bug fix created by William J. Roberts. Read his comments about the fix
45 | // here: http://www.codeproject.com/useritems/ListViewDragDropManager.asp?msg=1911611#xx1911611xx
46 | return relativeTo.PointFromScreen( new Point( (double)mouse.X, (double)mouse.Y ) );
47 |
48 | #region Commented Out
49 | //System.Windows.Interop.HwndSource presentationSource =
50 | // (System.Windows.Interop.HwndSource)PresentationSource.FromVisual( relativeTo );
51 | //ScreenToClient( presentationSource.Handle, ref mouse );
52 | //GeneralTransform transform = relativeTo.TransformToAncestor( presentationSource.RootVisual );
53 | //Point offset = transform.Transform( new Point( 0, 0 ) );
54 | //return new Point( mouse.X - offset.X, mouse.Y - offset.Y );
55 | #endregion // Commented Out
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/QuickWaveBank/Extracting/ADPCMConverter.cs:
--------------------------------------------------------------------------------
1 | /* MSADPCMToPCM - Public Domain MSADPCM Decoder
2 | * https://github.com/flibitijibibo/MSADPCMToPCM
3 | *
4 | * Written by Ethan "flibitijibibo" Lee
5 | * http://www.flibitijibibo.com/
6 | *
7 | * Released under public domain.
8 | * No warranty implied; use at your own risk.
9 | *
10 | * For more on the MSADPCM format, see the MultimediaWiki:
11 | * http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM
12 | */
13 | using System;
14 | using System.Collections.Generic;
15 | using System.IO;
16 | using System.Linq;
17 | using System.Text;
18 | using System.Threading.Tasks;
19 |
20 | namespace QuickWaveBank.Extracting {
21 | public static class ADPCMConverter {
22 | /**
23 | * A bunch of magical numbers that predict the sample data from the
24 | * MSADPCM wavedata. Do not attempt to understand at all costs!
25 | */
26 | private static readonly int[] adaptionTable = {
27 | 230, 230, 230, 230, 307, 409, 512, 614,
28 | 768, 614, 512, 409, 307, 230, 230, 230
29 | };
30 | private static readonly int[] adaptCoeff_1 = {
31 | 256, 512, 0, 192, 240, 460, 392
32 | };
33 | private static readonly int[] adaptCoeff_2 = {
34 | 0, -256, 0, 64, 0, -208, -232
35 | };
36 |
37 | /**
38 | * Splits the MSADPCM samples from each byte block.
39 | *
40 | * @param block An MSADPCM sample byte
41 | * @param nibbleBlock we copy the parsed shorts into here
42 | */
43 | private static void getNibbleBlock(int block, int[] nibbleBlock) {
44 | nibbleBlock[0] = (int)((uint)block >> 4); // Upper half
45 | nibbleBlock[1] = (int)(block & 0xF); // Lower half
46 | }
47 |
48 | /**
49 | * Calculates PCM samples based on previous samples and a nibble input.
50 | *
51 | * @param nibble A parsed MSADPCM sample we got from getNibbleBlock
52 | * @param predictor The predictor we get from the MSADPCM block's preamble
53 | * @param sample_1 The first sample we use to predict the next sample
54 | * @param sample_2 The second sample we use to predict the next sample
55 | * @param delta Used to calculate the final sample
56 | * @return The calculated PCM sample
57 | */
58 | private static short CalculateSample(
59 | int nibble,
60 | int predictor,
61 | short[] sample_1,
62 | short[] sample_2,
63 | short[] delta
64 | ) {
65 | // Get a signed number out of the nibble. We need to retain the
66 | // original nibble value for when we access AdaptionTable[].
67 | byte signedNibble = (byte) nibble;// sbyte
68 | if ((signedNibble & 0x8) == 0x8) {
69 | signedNibble -= 0x10;
70 | }
71 |
72 | // Calculate new sample
73 | int sampleInt = (
74 | ((sample_1[0] * adaptCoeff_1[predictor]) +
75 | (sample_2[0] * adaptCoeff_2[predictor])
76 | ) / 256
77 | );
78 | sampleInt += signedNibble * delta[0];
79 |
80 | // Clamp result to 16-bit
81 | short sample;
82 | if (sampleInt < short.MinValue) {
83 | sample = short.MinValue;
84 | }
85 | else if (sampleInt > short.MaxValue) {
86 | sample = short.MaxValue;
87 | }
88 | else {
89 | sample = (short)sampleInt;
90 | }
91 |
92 | // Shuffle samples, get new delta
93 | sample_2[0] = sample_1[0];
94 | sample_1[0] = sample;
95 | delta[0] = (short)(adaptionTable[nibble] * delta[0] / 256);
96 |
97 | // Saturate the delta to a lower bound of 16
98 | if (delta[0] < 16)
99 | delta[0] = 16;
100 |
101 | return sample;
102 | }
103 |
104 | /**
105 | * Decodes MSADPCM data to signed 16-bit PCM data.
106 | *
107 | * @param source A ByteBuffer containing the headerless MSADPCM data
108 | * @param numChannels The number of channels (WAVEFORMATEX nChannels)
109 | * @param blockAlign The ADPCM block size (WAVEFORMATEX nBlockAlign)
110 | * @return A byte array containing the raw 16-bit PCM wavedata
111 | *
112 | * NOTE: The original MSADPCMToPCM class returns as a short[] array!
113 | */
114 | public static byte[] ConvertToPCM(byte[] source, short numChannels, short blockAlign) {
115 | //source.order(ByteOrder.LITTLE_ENDIAN);
116 | BinaryReader reader = new BinaryReader(new MemoryStream(source));
117 | try {
118 | // We write to output when reading the PCM data, then we convert
119 | // it back to a short array at the end.
120 | MemoryStream outStream = new MemoryStream();
121 | BinaryWriter writer = new BinaryWriter(outStream);
122 | //ByteArrayOutputStream output = new ByteArrayOutputStream();
123 | //BufferWriter pcmOut = new BufferWriter(output);
124 | //pcmOut.setOrder(ByteOrder.LITTLE_ENDIAN);
125 |
126 | // We'll be using this to get each sample from the blocks.
127 | int[] nibbleBlock = new int[2];
128 |
129 | // Assuming the whole stream is what we want.
130 | long fileLength = source.Length - blockAlign;
131 |
132 | // Mono or Stereo?
133 | if (numChannels == 1) {
134 | // Read to the end of the file.
135 | while ((int)reader.BaseStream.Position <= fileLength) {
136 | // Read block preamble
137 | int predictor = reader.ReadByte() & 0xff;
138 | short[] delta = { reader.ReadInt16() };
139 | short[] sample_1 = { reader.ReadInt16() };
140 | short[] sample_2 = { reader.ReadInt16() };
141 |
142 | // Send the initial samples straight to PCM out.
143 | writer.Write(sample_2[0]);
144 | writer.Write(sample_1[0]);
145 |
146 | // Go through the bytes in this MSADPCM block.
147 | for (int bytes = 0; bytes < (blockAlign + 15); bytes++) {
148 | // Each sample is one half of a nibbleBlock.
149 | getNibbleBlock(reader.ReadByte() & 0xff, nibbleBlock);
150 | for (int i = 0; i < 2; i++) {
151 | writer.Write(
152 | CalculateSample(
153 | nibbleBlock[i],
154 | predictor,
155 | sample_1,
156 | sample_2,
157 | delta
158 | )
159 | );
160 | }
161 | }
162 | }
163 | }
164 | else if (numChannels == 2) {
165 | // Read to the end of the file.
166 | while ((int)reader.BaseStream.Position <= fileLength) {
167 | // Read block preamble
168 | int l_predictor = reader.ReadByte() & 0xff;
169 | int r_predictor = reader.ReadByte() & 0xff;
170 | short[] l_delta = { reader.ReadInt16() };
171 | short[] r_delta = { reader.ReadInt16() };
172 | short[] l_sample_1 = { reader.ReadInt16() };
173 | short[] r_sample_1 = { reader.ReadInt16() };
174 | short[] l_sample_2 = { reader.ReadInt16() };
175 | short[] r_sample_2 = { reader.ReadInt16() };
176 |
177 | // Send the initial samples straight to PCM out.
178 | writer.Write(l_sample_2[0]);
179 | writer.Write(r_sample_2[0]);
180 | writer.Write(l_sample_1[0]);
181 | writer.Write(r_sample_1[0]);
182 |
183 | // Go through the bytes in this MSADPCM block.
184 | for (int bytes = 0; bytes < ((blockAlign + 15) * 2); bytes++) {
185 | // Each block carries one left/right sample.
186 | getNibbleBlock(reader.ReadByte() & 0xff, nibbleBlock);
187 |
188 | // Left channel...
189 | writer.Write(
190 | CalculateSample(
191 | nibbleBlock[0],
192 | l_predictor,
193 | l_sample_1,
194 | l_sample_2,
195 | l_delta
196 | )
197 | );
198 |
199 | // Right channel...
200 | writer.Write(
201 | CalculateSample(
202 | nibbleBlock[1],
203 | r_predictor,
204 | r_sample_1,
205 | r_sample_2,
206 | r_delta
207 | )
208 | );
209 | }
210 | }
211 | }
212 | else {
213 | throw new Exception("MSADPCM WAVEDATA IS NOT MONO OR STEREO!");
214 | }
215 |
216 | // We're done writing PCM data...
217 | writer.Close();
218 |
219 | // Return the array.
220 | return outStream.ToArray();
221 | }
222 | catch (IOException ex) {
223 | throw new Exception("This should not happen as no I/O"
224 | + " resources are used", ex);
225 | }
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/QuickWaveBank/Extracting/FFmpeg.cs:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (C) 2014-2015 Anton Gustafsson
3 | *
4 | *
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included in
13 | * all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | * SOFTWARE.
22 | ******************************************************************************/
23 | using System;
24 | using System.Collections.Generic;
25 | using System.Diagnostics;
26 | using System.IO;
27 | using System.Linq;
28 | using System.Reflection;
29 | using System.Text;
30 | using System.Threading.Tasks;
31 | using System.Windows;
32 | using QuickWaveBank.Properties;
33 | using QuickWaveBank.Util;
34 |
35 | namespace QuickWaveBank.Extracting {
36 | public static class FFmpeg {
37 | //========== CONSTANTS ===========
38 | #region Constants
39 |
40 | /**The path of the temporary executable.*/
41 | private static readonly string TempFFmpeg = Path.Combine(Path.GetTempPath(), "TriggersToolsGames", "ffmpeg.exe");
42 |
43 | #endregion
44 | //========= CONSTRUCTORS =========
45 | #region Constructors
46 |
47 | /**Extracts FFmpeg.*/
48 | static FFmpeg() {
49 | EmbeddedResources.Extract(TempFFmpeg, Resources.ffmpeg);
50 | }
51 |
52 | #endregion
53 | //========== CONVERTING ==========
54 | #region Converting
55 |
56 | /**Converts the specified input file to wave format.*/
57 | public static bool Convert(string input, string output) {
58 | List command = new List();
59 | string arguments =
60 | "-i \"" + Path.GetFullPath(input) + "\" " +
61 | "-acodec pcm_s16le " +
62 | "-nostdin " +
63 | "-ab 128k " +
64 | "-map_metadata -1 " +
65 | "-y " +
66 | "\"" + Path.GetFullPath(output) + "\"";
67 |
68 | ProcessStartInfo start = new ProcessStartInfo();
69 | start.FileName = TempFFmpeg;
70 | start.Arguments = arguments;
71 | start.WindowStyle = ProcessWindowStyle.Hidden;
72 |
73 | Process process = Process.Start(start);
74 | process.WaitForExit();
75 | return (process.ExitCode == 0);
76 | }
77 |
78 | #endregion
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/QuickWaveBank/Extracting/TerrariaLocator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using Microsoft.Win32;
8 |
9 | namespace QuickWaveBank.Extracting {
10 | /**Finds the Terraria Content folder.*/
11 | public static class TerrariaLocator {
12 | //=========== MEMBERS ============
13 | #region Members
14 |
15 | /**The located or empty Terraria Content folder.*/
16 | public static readonly string TerrariaContentDirectory;
17 |
18 | #endregion
19 | //========= CONSTRUCTORS =========
20 | #region Constructors
21 |
22 | /**Start looking for the Terraria Content folder.*/
23 | static TerrariaLocator() {
24 | TerrariaContentDirectory = FindTerrariaContentDirectory();
25 | }
26 |
27 | #endregion
28 | //=========== LOCATORS ===========
29 | #region Locators
30 |
31 | /**Starts looking for the Terraria Content folder.*/
32 | private static string FindTerrariaContentDirectory() {
33 | try {
34 | // Check the windows registry for steam installation path
35 | string steamPath = Registry.GetValue("HKEY_CURRENT_USER\\Software\\Valve\\Steam", "SteamPath", null) as string;
36 | string result = SeekDirectory(steamPath);
37 | if (result != null) {
38 | return result;
39 | }
40 | }
41 | catch { }
42 | try {
43 | // Try to find relevant environment variables
44 | foreach (KeyValuePair envVar in Environment.GetEnvironmentVariables()) {
45 | string result = null;
46 | if (envVar.Key.ToLower().Contains("terraria") ||
47 | envVar.Key.ToLower().Contains("tapi")) {
48 | result = SeekDirectory(envVar.Value);
49 | }
50 | else if (envVar.Key.ToLower().Contains("steam")) {
51 | result = SeekDirectory(envVar.Value);
52 | }
53 | if (result != null) {
54 | return result;
55 | }
56 | }
57 | }
58 | catch { }
59 |
60 | // If nothing other works, then prompt the user
61 | return null;
62 | }
63 |
64 | /**Seeks a directory for the Terraria Content folder.*/
65 | private static string SeekDirectory(string steamDirectory) {
66 | if (steamDirectory == null || !Directory.Exists(steamDirectory)) {
67 | return null;
68 | }
69 |
70 | string path = Path.Combine(steamDirectory, "SteamApps", "Common", "Terraria", "Content");
71 | if (Directory.Exists(path)) {
72 | path = GetProperDirectoryCapitalization(new DirectoryInfo(path));
73 | if (path.Length >= 2 && path[1] == ':') {
74 | path = char.ToUpper(path[0]) + path.Substring(1);
75 | return path;
76 | }
77 | }
78 | return null;
79 | }
80 |
81 | #endregion
82 | //=========== HELPERS ============
83 | #region Helpers
84 |
85 | /**Gets the proper capitalization of a path so it looks nice.*/
86 | private static string GetProperDirectoryCapitalization(DirectoryInfo dirInfo) {
87 | DirectoryInfo parentDirInfo = dirInfo.Parent;
88 | if (null == parentDirInfo)
89 | return dirInfo.Name;
90 | return Path.Combine(GetProperDirectoryCapitalization(parentDirInfo),
91 | parentDirInfo.GetDirectories(dirInfo.Name)[0].Name);
92 | }
93 | /**Recursively gets the proper capitalization of a path so it looks nice.*/
94 | private static string GetProperFilePathCapitalization(string filename) {
95 | FileInfo fileInfo = new FileInfo(filename);
96 | DirectoryInfo dirInfo = fileInfo.Directory;
97 | return Path.Combine(GetProperDirectoryCapitalization(dirInfo),
98 | dirInfo.GetFiles(fileInfo.Name)[0].Name);
99 | }
100 |
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/QuickWaveBank/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("Quick Wave Bank")]
11 | [assembly: AssemblyDescription("Quick Wave Bank - A quick and easy wave bank builder for Terraria.")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("Trigger's Tools & Games")]
14 | [assembly: AssemblyProduct("QuickWaveBank")]
15 | [assembly: AssemblyCopyright("Copyright © Robert Jordan 2020")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.3.0")]
55 | [assembly: AssemblyFileVersion("1.0.3.0")]
56 | [assembly: Guid("81CB3338-5599-449F-A2A4-2C37A245551F")]
57 | [assembly: NeutralResourcesLanguage("en-US")]
58 |
59 |
--------------------------------------------------------------------------------
/QuickWaveBank/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\Icons\About.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Resources\Icons\Advanced.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Resources\Icons\AppError.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Resources\Icons\Browse.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\..\BuildConsole\bin\DebugRelease\BuildConsole.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
135 |
136 |
137 | ..\Resources\Icons\BuildWaveBank.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
138 |
139 |
140 | ..\Resources\Icons\Compression.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
141 |
142 |
143 | ..\Resources\Icons\Credits.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
144 |
145 |
146 | ..\Resources\Icons\DragAndDrop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
147 |
148 |
149 | ..\Resources\Icons\Empty.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
150 |
151 |
152 | ..\Resources\Icons\ErrorIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
153 |
154 |
155 | ..\Resources\Icons\Exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
156 |
157 |
158 | ..\Resources\Icons\ExtractWaveBank.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
159 |
160 |
161 | ..\Resources\ffmpeg.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
162 |
163 |
164 | ..\Resources\Icons\Github.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
165 |
166 |
167 | ..\Resources\Icons\Help.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
168 |
169 |
170 | ..\Resources\Icons\InfoIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
171 |
172 |
173 | ..\Resources\Icons\LoadList.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
174 |
175 |
176 | ..\Resources\Logo112.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
177 |
178 |
179 | ..\Resources\Icons\MoveDown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
180 |
181 |
182 | ..\Resources\Icons\MoveUp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
183 |
184 |
185 | ..\Resources\Icons\NewWaveList.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
186 |
187 |
188 | ..\Resources\Icons\Next.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
189 |
190 |
191 | ..\Resources\Icons\Pause.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
192 |
193 |
194 | ..\Resources\Icons\PauseUnflipped.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
195 |
196 |
197 | ..\Resources\Icons\Play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
198 |
199 |
200 | ..\Resources\Icons\PlayUnflipped.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
201 |
202 |
203 | ..\Resources\Icons\Previous.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
204 |
205 |
206 | ..\Resources\Icons\QuestionIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
207 |
208 |
209 | ..\Resources\Icons\SaveList.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
210 |
211 |
212 | ..\Resources\Icons\SaveListAs.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
213 |
214 |
215 | ..\Resources\Icons\ShowLog.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
216 |
217 |
218 | ..\Resources\Icons\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
219 |
220 |
221 | ..\Resources\Icons\Streaming.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
222 |
223 |
224 | ..\Resources\Icons\TerrariaIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
225 |
226 |
227 | ..\Resources\Icons\TrackNames.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
228 |
229 |
230 | ..\Resources\Icons\VolumeHigh.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
231 |
232 |
233 | ..\Resources\Icons\VolumeLow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
234 |
235 |
236 | ..\Resources\Icons\VolumeMute.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
237 |
238 |
239 | ..\Resources\Icons\VolumeNone.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
240 |
241 |
242 | ..\Resources\Icons\WarningIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
243 |
244 |
245 | ..\Resources\Icons\WaveAdd.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
246 |
247 |
248 | ..\Resources\Icons\WaveAddFolder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
249 |
250 |
251 | ..\Resources\WaveBankProject.xap;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
252 |
253 |
254 | ..\Resources\Icons\WaveRemove.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
255 |
256 |
257 | ..\Resources\Icons\WaveRemoveAll.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
258 |
259 |
260 | ..\Resources\XactBld3.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
261 |
262 |
263 | ..\Resources\Icons\Convert.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
264 |
265 |
266 | ..\Resources\Icons\SaveConfirmation.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
267 |
268 |
--------------------------------------------------------------------------------
/QuickWaveBank/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace QuickWaveBank.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string OutputFile {
30 | get {
31 | return ((string)(this["OutputFile"]));
32 | }
33 | set {
34 | this["OutputFile"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
41 | public bool DragAndDrop {
42 | get {
43 | return ((bool)(this["DragAndDrop"]));
44 | }
45 | set {
46 | this["DragAndDrop"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
53 | public bool ShowLog {
54 | get {
55 | return ((bool)(this["ShowLog"]));
56 | }
57 | set {
58 | this["ShowLog"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
65 | public bool TrackNames {
66 | get {
67 | return ((bool)(this["TrackNames"]));
68 | }
69 | set {
70 | this["TrackNames"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
77 | public bool Streaming {
78 | get {
79 | return ((bool)(this["Streaming"]));
80 | }
81 | set {
82 | this["Streaming"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("xWMA")]
89 | public string Format {
90 | get {
91 | return ((string)(this["Format"]));
92 | }
93 | set {
94 | this["Format"] = value;
95 | }
96 | }
97 |
98 | [global::System.Configuration.UserScopedSettingAttribute()]
99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
100 | [global::System.Configuration.DefaultSettingValueAttribute("60")]
101 | public int WMAQuality {
102 | get {
103 | return ((int)(this["WMAQuality"]));
104 | }
105 | set {
106 | this["WMAQuality"] = value;
107 | }
108 | }
109 |
110 | [global::System.Configuration.UserScopedSettingAttribute()]
111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
112 | [global::System.Configuration.DefaultSettingValueAttribute("128")]
113 | public int ADPCMSamplesPerBlock {
114 | get {
115 | return ((int)(this["ADPCMSamplesPerBlock"]));
116 | }
117 | set {
118 | this["ADPCMSamplesPerBlock"] = value;
119 | }
120 | }
121 |
122 | [global::System.Configuration.UserScopedSettingAttribute()]
123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
124 | [global::System.Configuration.DefaultSettingValueAttribute("0.5")]
125 | public double Volume {
126 | get {
127 | return ((double)(this["Volume"]));
128 | }
129 | set {
130 | this["Volume"] = value;
131 | }
132 | }
133 |
134 | [global::System.Configuration.UserScopedSettingAttribute()]
135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
136 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
137 | public bool Muted {
138 | get {
139 | return ((bool)(this["Muted"]));
140 | }
141 | set {
142 | this["Muted"] = value;
143 | }
144 | }
145 |
146 | [global::System.Configuration.UserScopedSettingAttribute()]
147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
148 | [global::System.Configuration.DefaultSettingValueAttribute("Ask")]
149 | public string ConvertOption {
150 | get {
151 | return ((string)(this["ConvertOption"]));
152 | }
153 | set {
154 | this["ConvertOption"] = value;
155 | }
156 | }
157 |
158 | [global::System.Configuration.UserScopedSettingAttribute()]
159 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
160 | [global::System.Configuration.DefaultSettingValueAttribute("")]
161 | public string LastFolderBrowser {
162 | get {
163 | return ((string)(this["LastFolderBrowser"]));
164 | }
165 | set {
166 | this["LastFolderBrowser"] = value;
167 | }
168 | }
169 |
170 | [global::System.Configuration.UserScopedSettingAttribute()]
171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
172 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
173 | public bool SaveConfirmation {
174 | get {
175 | return ((bool)(this["SaveConfirmation"]));
176 | }
177 | set {
178 | this["SaveConfirmation"] = value;
179 | }
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/QuickWaveBank/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | True
10 |
11 |
12 | False
13 |
14 |
15 | True
16 |
17 |
18 | False
19 |
20 |
21 | xWMA
22 |
23 |
24 | 60
25 |
26 |
27 | 128
28 |
29 |
30 | 0.5
31 |
32 |
33 | False
34 |
35 |
36 | Ask
37 |
38 |
39 |
40 |
41 |
42 | True
43 |
44 |
45 |
--------------------------------------------------------------------------------
/QuickWaveBank/QuickWaveBank.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B550B2E1-A47D-454C-96D9-F85A8980D8FF}
8 | WinExe
9 | Properties
10 | QuickWaveBank
11 | QuickWaveBank
12 | v4.5.2
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 | App.ico
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 4.0
54 |
55 |
56 |
57 |
58 |
59 | ..\packages\Extended.Wpf.Toolkit.3.1\lib\net40\Xceed.Wpf.Toolkit.dll
60 | True
61 |
62 |
63 |
64 |
65 | MSBuild:Compile
66 | Designer
67 |
68 |
69 |
70 |
71 | IntSpinner.xaml
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | AboutWindow.xaml
84 |
85 |
86 | CompressionDialog.xaml
87 |
88 |
89 | CreditsWindow.xaml
90 |
91 |
92 | ErrorLogWindow.xaml
93 |
94 |
95 | ErrorMessageBox.xaml
96 |
97 |
98 |
99 | TriggerMessageBox.xaml
100 |
101 |
102 | VolumeDialog.xaml
103 |
104 |
105 |
106 |
107 |
108 | MSBuild:Compile
109 | Designer
110 |
111 |
112 | MSBuild:Compile
113 | Designer
114 |
115 |
116 | App.xaml
117 | Code
118 |
119 |
120 | MainWindow.xaml
121 | Code
122 |
123 |
124 | MSBuild:Compile
125 | Designer
126 |
127 |
128 | Designer
129 | MSBuild:Compile
130 |
131 |
132 | MSBuild:Compile
133 | Designer
134 |
135 |
136 | MSBuild:Compile
137 | Designer
138 |
139 |
140 | MSBuild:Compile
141 | Designer
142 |
143 |
144 | MSBuild:Compile
145 | Designer
146 |
147 |
148 | Designer
149 | MSBuild:Compile
150 |
151 |
152 |
153 |
154 | Code
155 |
156 |
157 | True
158 | True
159 | Resources.resx
160 |
161 |
162 | True
163 | Settings.settings
164 | True
165 |
166 |
167 | ResXFileCodeGenerator
168 | Resources.Designer.cs
169 |
170 |
171 |
172 | SettingsSingleFileGenerator
173 | Settings.Designer.cs
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 | {77dc12fa-d6fa-4a42-912e-0d8e7e4aa83f}
330 | BuildConsole
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 | %(Filename)%(Extension)
354 |
355 |
356 |
357 |
358 |
359 |
360 |
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/About.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/About.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Advanced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Advanced.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/AppError.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/AppError.ico
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Browse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Browse.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/BuildWaveBank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/BuildWaveBank.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Compression.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Compression.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Convert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Convert.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Credits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Credits.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/DragAndDrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/DragAndDrop.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Empty.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/ErrorIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/ErrorIcon.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Exit.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/ExtractWaveBank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/ExtractWaveBank.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Github.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Help.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/InfoIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/InfoIcon.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/LoadList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/LoadList.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/MoveDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/MoveDown.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/MoveUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/MoveUp.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/NewWaveList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/NewWaveList.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Next.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Pause.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/PauseUnflipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/PauseUnflipped.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Play.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/PlayUnflipped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/PlayUnflipped.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Previous.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/QuestionIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/QuestionIcon.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/SaveConfirmation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/SaveConfirmation.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/SaveList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/SaveList.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/SaveListAs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/SaveListAs.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/ShowLog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/ShowLog.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Stop.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/Streaming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/Streaming.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/TerrariaIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/TerrariaIcon.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/TrackNames.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/TrackNames.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/VolumeHigh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/VolumeHigh.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/VolumeLow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/VolumeLow.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/VolumeMute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/VolumeMute.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/VolumeNone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/VolumeNone.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WarningIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WarningIcon.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WaveAdd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WaveAdd.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WaveAddFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WaveAddFolder.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WaveBank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WaveBank.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WaveRemove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WaveRemove.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Icons/WaveRemoveAll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Icons/WaveRemoveAll.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/Logo112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/Logo112.png
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/WaveBankProject.xap:
--------------------------------------------------------------------------------
1 | Signature = XACT3;
2 | Version = 18;
3 | Content Version = 46;
4 | Release = February 2010;
5 |
6 | Options
7 | {
8 | Verbose Report = 0;
9 | Generate C/C++ Headers = 1;
10 | }
11 |
12 | Global Settings
13 | {
14 | Xbox File = Xbox\WaveBankProject.xgs;
15 | Windows File = WaveBankProject.xgs;
16 | Header File = WaveBankProject.h;
17 | Exclude Category Names = 0;
18 | Exclude Variable Names = 0;
19 | Last Modified Low = 30615028;
20 | Last Modified High = 700044767;
21 |
22 | Category
23 | {
24 | Name = Global;
25 | Public = 1;
26 | Background Music = 0;
27 | Volume = 0;
28 |
29 | Category Entry
30 | {
31 | }
32 |
33 | Instance Limit
34 | {
35 | Max Instances = 255;
36 | Behavior = 0;
37 |
38 | Crossfade
39 | {
40 | Fade In = 0;
41 | Fade Out = 0;
42 | Crossfade Type = 0;
43 | }
44 | }
45 | }
46 |
47 | Category
48 | {
49 | Name = Default;
50 | Public = 1;
51 | Background Music = 0;
52 | Volume = 0;
53 |
54 | Category Entry
55 | {
56 | Name = Global;
57 | }
58 |
59 | Instance Limit
60 | {
61 | Max Instances = 255;
62 | Behavior = 0;
63 |
64 | Crossfade
65 | {
66 | Fade In = 0;
67 | Fade Out = 0;
68 | Crossfade Type = 0;
69 | }
70 | }
71 | }
72 |
73 | Category
74 | {
75 | Name = Music;
76 | Public = 1;
77 | Background Music = 1;
78 | Volume = 0;
79 |
80 | Category Entry
81 | {
82 | Name = Global;
83 | }
84 |
85 | Instance Limit
86 | {
87 | Max Instances = 255;
88 | Behavior = 0;
89 |
90 | Crossfade
91 | {
92 | Fade In = 0;
93 | Fade Out = 0;
94 | Crossfade Type = 0;
95 | }
96 | }
97 | }
98 |
99 | Variable
100 | {
101 | Name = OrientationAngle;
102 | Public = 1;
103 | Global = 0;
104 | Internal = 0;
105 | External = 0;
106 | Monitored = 1;
107 | Reserved = 1;
108 | Read Only = 0;
109 | Time = 0;
110 | Value = 0.000000;
111 | Initial Value = 0.000000;
112 | Min = -180.000000;
113 | Max = 180.000000;
114 | }
115 |
116 | Variable
117 | {
118 | Name = DopplerPitchScalar;
119 | Public = 1;
120 | Global = 0;
121 | Internal = 0;
122 | External = 0;
123 | Monitored = 1;
124 | Reserved = 1;
125 | Read Only = 0;
126 | Time = 0;
127 | Value = 1.000000;
128 | Initial Value = 1.000000;
129 | Min = 0.000000;
130 | Max = 4.000000;
131 | }
132 |
133 | Variable
134 | {
135 | Name = SpeedOfSound;
136 | Public = 1;
137 | Global = 1;
138 | Internal = 0;
139 | External = 0;
140 | Monitored = 1;
141 | Reserved = 1;
142 | Read Only = 0;
143 | Time = 0;
144 | Value = 343.500000;
145 | Initial Value = 343.500000;
146 | Min = 0.000000;
147 | Max = 1000000.000000;
148 | }
149 |
150 | Variable
151 | {
152 | Name = ReleaseTime;
153 | Public = 1;
154 | Global = 0;
155 | Internal = 1;
156 | External = 1;
157 | Monitored = 1;
158 | Reserved = 1;
159 | Read Only = 1;
160 | Time = 1;
161 | Value = 0.000000;
162 | Initial Value = 0.000000;
163 | Min = 0.000000;
164 | Max = 15000.000000;
165 | }
166 |
167 | Variable
168 | {
169 | Name = AttackTime;
170 | Public = 1;
171 | Global = 0;
172 | Internal = 1;
173 | External = 1;
174 | Monitored = 1;
175 | Reserved = 1;
176 | Read Only = 1;
177 | Time = 1;
178 | Value = 0.000000;
179 | Initial Value = 0.000000;
180 | Min = 0.000000;
181 | Max = 15000.000000;
182 | }
183 |
184 | Variable
185 | {
186 | Name = NumCueInstances;
187 | Public = 1;
188 | Global = 0;
189 | Internal = 1;
190 | External = 1;
191 | Monitored = 1;
192 | Reserved = 1;
193 | Read Only = 1;
194 | Time = 0;
195 | Value = 0.000000;
196 | Initial Value = 0.000000;
197 | Min = 0.000000;
198 | Max = 1024.000000;
199 | }
200 |
201 | Variable
202 | {
203 | Name = Distance;
204 | Public = 1;
205 | Global = 0;
206 | Internal = 0;
207 | External = 0;
208 | Monitored = 1;
209 | Reserved = 1;
210 | Read Only = 0;
211 | Time = 0;
212 | Value = 0.000000;
213 | Initial Value = 0.000000;
214 | Min = 0.000000;
215 | Max = 1000000.000000;
216 | }
217 |
218 | Compression Preset
219 | {
220 | Name = Wave Bank Compression Preset;
221 | Xbox Format Tag = 353;
222 | WMA Quality = 60;
223 | PC Format Tag = 353;
224 | WMA Quality = 60;
225 | }
226 | }
227 |
228 | Wave Bank
229 | {
230 | Name = Wave Bank;
231 | Xbox File = Xbox\Wave Bank.xwb;
232 | Windows File = Wave Bank.xwb;
233 | Xbox Bank Path Edited = 0;
234 | Windows Bank Path Edited = 1;
235 | Streaming = 0;
236 | Seek Tables = 1;
237 | Compression Preset Name = Wave Bank Compression Preset;
238 | Header Last Modified Low = 0;
239 | Header Last Modified High = 0;
240 | Bank Last Revised Low = 3730249810;
241 | Bank Last Revised High = 30615204;
242 | }
243 |
--------------------------------------------------------------------------------
/QuickWaveBank/Resources/ffmpeg.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/Resources/ffmpeg.exe
--------------------------------------------------------------------------------
/QuickWaveBank/Util/EmbeddedResources.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Runtime.InteropServices;
6 | using System.IO;
7 | using System.Reflection;
8 | using System.Diagnostics;
9 | using System.ComponentModel;
10 |
11 | namespace QuickWaveBank.Util {
12 | /**Extract embedded resources.*/
13 | public static class EmbeddedResources {
14 | //========== EXTRACTING ==========
15 | #region Extracting
16 |
17 | /**Extract an embedded resource from byte array.*/
18 | public static void Extract(string resourcePath, byte[] resourceBytes) {
19 | string dirName = Path.GetDirectoryName(resourcePath);
20 | if (!Directory.Exists(dirName)) {
21 | Directory.CreateDirectory(dirName);
22 | }
23 |
24 | bool rewrite = true;
25 | if (File.Exists(resourcePath)) {
26 | byte[] existing = File.ReadAllBytes(resourcePath);
27 | if (resourceBytes.SequenceEqual(existing)) {
28 | rewrite = false;
29 | }
30 | }
31 | if (rewrite) {
32 | File.WriteAllBytes(resourcePath, resourceBytes);
33 | }
34 | }
35 | /**Extract an embedded resource from stream.*/
36 | public static void Extract(string resourcePath, Stream resourceStream) {
37 | byte[] resourceBytes = new byte[resourceStream.Length];
38 | resourceStream.Read(resourceBytes, 0, resourceBytes.Length);
39 |
40 | Extract(resourcePath, resourceBytes);
41 | }
42 | /**Extract an embedded resource from name.*/
43 | public static void Extract(string resourcePath, string resourceName) {
44 | Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
45 | Extract(resourcePath, resourceStream);
46 | }
47 |
48 | #endregion
49 | //=========== LOADING ============
50 | #region Loading
51 |
52 | /**Load a dll.*/
53 | public static void LoadDll(string dllPath) {
54 | IntPtr h = LoadLibrary(dllPath);
55 | if (h == IntPtr.Zero) {
56 | Exception e = new Win32Exception();
57 | throw new DllNotFoundException("Unable to load library: " + dllPath, e);
58 | }
59 | }
60 |
61 | #endregion
62 | //============ NATIVE ============
63 | #region Native
64 |
65 | [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
66 | static extern IntPtr LoadLibrary(string lpFileName);
67 |
68 | #endregion
69 | }
70 | }
--------------------------------------------------------------------------------
/QuickWaveBank/Util/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Management;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace QuickWaveBank.Util {
11 | /**A collection of useful extensions.*/
12 | public static class Extensions {
13 | /**Fills an array with a value.*/
14 | public static void Fill(this T[] array, T with) {
15 | for (int i = 0; i < array.Length; i++) {
16 | array[i] = with;
17 | }
18 | }
19 | /**Swaps two items within an array.*/
20 | public static void Swap(this T[] array, int indexA, int indexB) {
21 | T swap = array[indexA];
22 | array[indexA] = array[indexB];
23 | array[indexB] = swap;
24 | }
25 | /**Moves an item within a list.*/
26 | public static void Move(this List list, int oldIndex, int newIndex) {
27 | T t = list[oldIndex];
28 | list.RemoveAt(oldIndex);
29 | list.Insert(newIndex, t);
30 | }
31 | /**Swaps two items within a list.*/
32 | public static void Swap(this List list, int indexA, int indexB) {
33 | T swap = list[indexA];
34 | list[indexA] = list[indexB];
35 | list[indexB] = swap;
36 | }
37 | /**Tests if a collection is empty.*/
38 | public static bool IsEmpty(this ICollection collection) {
39 | return (collection.Count == 0);
40 | }
41 | //https://stackoverflow.com/questions/30249873/process-kill-doesnt-seem-to-kill-the-process
42 | /**Kills a process and all of its children.*/
43 | public static void KillWithChildren(this Process process) {
44 | ManagementObjectSearcher processSearcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + process.Id);
45 | ManagementObjectCollection processCollection = processSearcher.Get();
46 |
47 | try {
48 | if (!process.HasExited) process.Kill();
49 | }
50 | catch (ArgumentException) { } // Process already exited.
51 |
52 | if (processCollection != null) {
53 | foreach (ManagementObject mo in processCollection) {
54 | try {
55 | KillWithChildren(Process.GetProcessById(Convert.ToInt32(mo["ProcessID"]))); //kill child processes(also kills childrens of childrens etc.)
56 | }
57 | catch { }
58 | }
59 | }
60 | }
61 | /**Shows a process's window.*/
62 | public static void Show(this Process process) {
63 | ShowWindow(process.MainWindowHandle, SW_RESTORE);
64 | }
65 | /**Shows a process's window.*/
66 | public static void Hide(this Process process) {
67 | ShowWindow(process.MainWindowHandle, SW_HIDE);
68 | }
69 |
70 | [DllImport("user32.dll")]
71 | private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
72 |
73 | private const int SW_RESTORE = 9;
74 | private const int SW_HIDE = 0;
75 |
76 | /**Sets an enum's flag.*/
77 | public static TEnum SetFlag(this Enum enumValue, TEnum flag, bool set = true)
78 | where TEnum : struct, IComparable, IFormattable, IConvertible {
79 | Type underlyingType = Enum.GetUnderlyingType(enumValue.GetType());
80 |
81 | // note: AsInt mean: math integer vs enum (not the c# int type)
82 | dynamic valueAsInt = Convert.ChangeType(enumValue, underlyingType);
83 | dynamic flagAsInt = Convert.ChangeType(flag, underlyingType);
84 | if (set)
85 | valueAsInt |= flagAsInt;
86 | else
87 | valueAsInt &= ~flagAsInt;
88 | return (TEnum)valueAsInt;
89 | }
90 | /**Unsets an enum's flag.*/
91 | public static TEnum UnsetFlag(this Enum enumValue, TEnum flag)
92 | where TEnum : struct, IComparable, IFormattable, IConvertible {
93 | Type underlyingType = Enum.GetUnderlyingType(enumValue.GetType());
94 |
95 | // note: AsInt mean: math integer vs enum (not the c# int type)
96 | dynamic valueAsInt = Convert.ChangeType(enumValue, underlyingType);
97 | dynamic flagAsInt = Convert.ChangeType(flag, underlyingType);
98 | valueAsInt &= ~flagAsInt;
99 | return (TEnum)valueAsInt;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/AboutWindow.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/AboutWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 | using System.Windows.Controls;
10 | using System.Windows.Data;
11 | using System.Windows.Documents;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Media.Imaging;
15 | using System.Windows.Shapes;
16 |
17 | namespace QuickWaveBank.Windows {
18 | /**The window showing information about the program.*/
19 | public partial class AboutWindow : Window {
20 | //========= CONSTRUCTORS =========
21 | #region Constructors
22 |
23 | /**Constructs the about window.*/
24 | public AboutWindow() {
25 | InitializeComponent();
26 |
27 | DateTime buildDate = GetLinkerTime(Assembly.GetExecutingAssembly());
28 | this.labelVersion.Content = Assembly.GetExecutingAssembly().GetName().Version.ToString() + " Release";
29 | this.labelBuildDate.Content = buildDate.ToShortDateString() + " (" + buildDate.ToShortTimeString() + ")";
30 | }
31 |
32 | #endregion
33 | //=========== HELPERS ============
34 | #region Helpers
35 |
36 | /**Gets the build date of the program.*/
37 | private DateTime GetLinkerTime(Assembly assembly, TimeZoneInfo target = null) {
38 | var filePath = assembly.Location;
39 | const int c_PeHeaderOffset = 60;
40 | const int c_LinkerTimestampOffset = 8;
41 |
42 | var buffer = new byte[2048];
43 |
44 | using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
45 | stream.Read(buffer, 0, 2048);
46 |
47 | var offset = BitConverter.ToInt32(buffer, c_PeHeaderOffset);
48 | var secondsSince1970 = BitConverter.ToInt32(buffer, offset + c_LinkerTimestampOffset);
49 | var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
50 |
51 | var linkTimeUtc = epoch.AddSeconds(secondsSince1970);
52 |
53 | var tz = target ?? TimeZoneInfo.Local;
54 | var localTime = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tz);
55 |
56 | return localTime;
57 | }
58 |
59 | #endregion
60 | //============ EVENTS ============
61 | #region Events
62 |
63 | private void OnWindowLoaded(object sender, RoutedEventArgs e) {
64 | clientArea.Height = 214 + textBlockDescription.ActualHeight;
65 | }
66 |
67 | #endregion
68 | //=========== SHOWING ============
69 | #region Showing
70 |
71 | /**Shows the window.*/
72 | public static void Show(Window owner) {
73 | AboutWindow window = new AboutWindow();
74 | window.Owner = owner;
75 | window.ShowDialog();
76 | }
77 |
78 | #endregion
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/CompressionDialog.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/CompressionDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace QuickWaveBank.Windows {
16 | ///
17 | /// Interaction logic for CompressionDialog.xaml
18 | ///
19 | public partial class CompressionDialog : Window {
20 |
21 | private bool loaded = false;
22 | private CompressionFormats format;
23 | private int wmaQuality;
24 | private ADPCMSamplesPerBlock samplesPerBlock;
25 |
26 | public CompressionDialog() {
27 | InitializeComponent();
28 |
29 | format = Config.Format;
30 | wmaQuality = Config.WMAQuality;
31 | samplesPerBlock = Config.SamplesPerBlock;
32 |
33 | var formats = (CompressionFormats[])Enum.GetValues(typeof(CompressionFormats));
34 | for (int i = 0; i < formats.Length; i++) {
35 | comboBoxFormat.Items.Add(formats[i].ToString());
36 | if (format == formats[i])
37 | comboBoxFormat.SelectedIndex = i;
38 | }
39 |
40 | spinnerQuality.Value = Math.Max(1, Math.Min(100, wmaQuality));
41 |
42 | var samples = (ADPCMSamplesPerBlock[])Enum.GetValues(typeof(ADPCMSamplesPerBlock));
43 | for (int i = 0; i < samples.Length; i++) {
44 | comboBoxSamplesPerBlock.Items.Add(((int)samples[i]).ToString());
45 | if (samplesPerBlock == samples[i])
46 | comboBoxSamplesPerBlock.SelectedIndex = i;
47 | }
48 |
49 | labelSettings.Visibility = Visibility.Hidden;
50 | spinnerQuality.Visibility = Visibility.Hidden;
51 | comboBoxSamplesPerBlock.Visibility = Visibility.Hidden;
52 | switch (format) {
53 | case CompressionFormats.ADPCM:
54 | labelSettings.Content = "Samples Per Block";
55 | labelSettings.Visibility = Visibility.Visible;
56 | comboBoxSamplesPerBlock.Visibility = Visibility.Visible;
57 | break;
58 | case CompressionFormats.xWMA:
59 | labelSettings.Content = "Quility (1-100)";
60 | labelSettings.Visibility = Visibility.Visible;
61 | spinnerQuality.Visibility = Visibility.Visible;
62 | break;
63 | }
64 | }
65 |
66 | private void OnWindowLoaded(object sender, RoutedEventArgs e) {
67 | loaded = true;
68 | }
69 |
70 | private void OnFormatChanged(object sender, SelectionChangedEventArgs e) {
71 | if (!loaded)
72 | return;
73 | var formats = (CompressionFormats[])Enum.GetValues(typeof(CompressionFormats));
74 | for (int i = 0; i < formats.Length; i++) {
75 | if (((string)comboBoxFormat.SelectedItem) == formats[i].ToString()) {
76 | format = formats[i];
77 | break;
78 | }
79 | }
80 | labelSettings.Visibility = Visibility.Hidden;
81 | spinnerQuality.Visibility = Visibility.Hidden;
82 | comboBoxSamplesPerBlock.Visibility = Visibility.Hidden;
83 | switch (format) {
84 | case CompressionFormats.ADPCM:
85 | labelSettings.Content = "Samples Per Block";
86 | labelSettings.Visibility = Visibility.Visible;
87 | comboBoxSamplesPerBlock.Visibility = Visibility.Visible;
88 | break;
89 | case CompressionFormats.xWMA:
90 | labelSettings.Content = "Quility (1-100)";
91 | labelSettings.Visibility = Visibility.Visible;
92 | spinnerQuality.Visibility = Visibility.Visible;
93 | break;
94 | }
95 | }
96 |
97 | private void OnQualityChanged(object sender, Controls.ValueChangedEventArgs e) {
98 | if (!loaded)
99 | return;
100 | wmaQuality = spinnerQuality.Value;
101 | }
102 |
103 | private void OnSamplesPerBlockChanged(object sender, SelectionChangedEventArgs e) {
104 | if (!loaded)
105 | return;
106 | var samples = (ADPCMSamplesPerBlock[])Enum.GetValues(typeof(ADPCMSamplesPerBlock));
107 | for (int i = 0; i < samples.Length; i++) {
108 | if (int.Parse((string)comboBoxSamplesPerBlock.SelectedItem) == ((int)samples[i])) {
109 | samplesPerBlock = samples[i];
110 | break;
111 | }
112 | }
113 | }
114 |
115 | public static void Show(Window owner) {
116 | CompressionDialog dialog = new CompressionDialog();
117 | dialog.Owner = owner;
118 | dialog.ShowDialog();
119 | Config.Format = dialog.format;
120 | switch (Config.Format) {
121 | case CompressionFormats.ADPCM:
122 | Config.SamplesPerBlock = dialog.samplesPerBlock;
123 | break;
124 | case CompressionFormats.xWMA:
125 | Config.WMAQuality = dialog.wmaQuality;
126 | break;
127 | }
128 | }
129 | private void OnOK(object sender, RoutedEventArgs e) {
130 | DialogResult = true;
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/CreditsWindow.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 | Wave Bank extraction capabilities thanks to TExtract.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Wave Bank song conversion thanks to FFmpeg, which is under GNU Lesser General Public License version 2.1.
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Wave Bank building capabilities thanks to XNA Game Studio's XactBld3.exe.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Most icons from or modified from Fugue Icon Pack.
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/CreditsWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Windows;
4 | using System.Windows.Documents;
5 | using System.Windows.Navigation;
6 |
7 | namespace QuickWaveBank.Windows {
8 | /**A window to display credits for the program.*/
9 | public partial class CreditsWindow : Window {
10 | //========= CONSTRUCTORS =========
11 | #region Constructors
12 |
13 | /**Constructs the credits window.*/
14 | public CreditsWindow() {
15 | InitializeComponent();
16 | }
17 |
18 | #endregion
19 | //============ EVENTS ============
20 | #region Events
21 |
22 | private void OnRequestNavigate(object sender, RequestNavigateEventArgs e) {
23 | Process.Start((sender as Hyperlink).NavigateUri.ToString());
24 | }
25 |
26 | private void OnCloseClicked(object sender, RoutedEventArgs e) {
27 | DialogResult = true;
28 | }
29 |
30 | #endregion
31 | //=========== SHOWING ============
32 | #region Showing
33 |
34 | /**Shows the credits window.*/
35 | public static void Show(Window owner) {
36 | CreditsWindow window = new CreditsWindow();
37 | window.Owner = owner;
38 | window.ShowDialog();
39 | }
40 |
41 | #endregion
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/ErrorLogWindow.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/ErrorLogWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Shapes;
15 | using System.Windows.Shell;
16 |
17 | namespace QuickWaveBank.Windows {
18 | /**A log error.*/
19 | public struct LogError {
20 | /**True if the log item is a warning and not an error.*/
21 | public bool IsWarning;
22 | /**The log message.*/
23 | public string Message;
24 | /**The error/warning reason.*/
25 | public string Reason;
26 | /**Constructs a log error.*/
27 | public LogError(bool isWarning, string message, string reason) {
28 | IsWarning = isWarning;
29 | Message = message;
30 | Reason = reason;
31 | }
32 | }
33 |
34 | /**The log window for showing errors that occurred during file processing.*/
35 | public partial class ErrorLogWindow : Window {
36 | //=========== MEMBERS ============
37 | #region Members
38 |
39 | /**The number of lines written so far.*/
40 | int lines;
41 |
42 | #endregion
43 | //========= CONSTRUCTORS =========
44 | #region Constructors
45 |
46 | /**Constructs and sets up the error log window.*/
47 | private ErrorLogWindow(LogError[] errors) {
48 | InitializeComponent();
49 |
50 | lines = 0;
51 | textBlockMessage.Text = "";
52 | foreach (LogError log in errors) {
53 | if (lines >= 300) {
54 | textBlockMessage.Inlines.Add(new Run("Issues continued in log file..."));
55 | textBlockMessage.Inlines.Add(new LineBreak());
56 | break;
57 | }
58 | AddError(log);
59 | }
60 | }
61 |
62 | #endregion
63 | //=========== HELPERS ============
64 | #region Helpers
65 |
66 | /**Adds an error.*/
67 | private void AddError(LogError log) {
68 | //string[] logs = log.Message.Split('\n', StringSplitOptions.None);
69 | //if (logs.Length > 0) {
70 | Run run = new Run((log.IsWarning ? "Warning: " : "Error: ") + log.Message);
71 | ColorRun(log.IsWarning, run);
72 | textBlockMessage.Inlines.Add(run);
73 | textBlockMessage.Inlines.Add(new LineBreak());
74 | lines++;
75 | if (log.Reason != String.Empty) {
76 | run = new Run(" Reason: " + log.Reason);
77 | ColorRun(log.IsWarning, run);
78 | textBlockMessage.Inlines.Add(run);
79 | textBlockMessage.Inlines.Add(new LineBreak());
80 | lines++;
81 | }
82 | }
83 | /**Adds a Run with color based on if it is a warning or error.*/
84 | private void ColorRun(bool isWarning, Run run) {
85 | if (isWarning)
86 | run.Foreground = new SolidColorBrush(Colors.Orange);
87 | else
88 | run.Foreground = new SolidColorBrush(Colors.Red);
89 | }
90 |
91 | #endregion
92 | //============ EVENTS ============
93 | #region Events
94 |
95 | #endregion
96 | //=========== SHOWING ============
97 | #region Showing
98 |
99 | public static void Show(Window owner, LogError[] errors) {
100 | ErrorLogWindow window = new ErrorLogWindow(errors);
101 | if (owner == null || owner.Visibility != Visibility.Visible)
102 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
103 | else
104 | window.Owner = owner;
105 | window.ShowDialog();
106 | }
107 |
108 | #endregion
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/ErrorMessageBox.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/ErrorMessageBox.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Timers;
4 | using System.Windows;
5 | using System.Windows.Documents;
6 | using System.Windows.Input;
7 | using System.Windows.Navigation;
8 |
9 | namespace QuickWaveBank.Windows {
10 | /**Shows an error that occured in the program.*/
11 | public partial class ErrorMessageBox : Window {
12 | //=========== MEMBERS ============
13 | #region Members
14 |
15 | /**The exception that was raised.*/
16 | private Exception exception = null;
17 | /**The non-exception object that was raised.*/
18 | private object exceptionObject = null;
19 | /**True if viewing the full exception.*/
20 | private bool viewingFull = false;
21 | /**The timer for changing the copy button back to its original text.*/
22 | private Timer copyTimer = new Timer(1000);
23 | /**The text of the copy to clipboard button.*/
24 | private readonly string copyText;
25 |
26 | #endregion
27 | //========= CONSTRUCTORS =========
28 | #region Constructors
29 |
30 | /**Constructs the error message box with an exception.*/
31 | public ErrorMessageBox(Exception exception, bool alwaysContinue) {
32 | InitializeComponent();
33 |
34 | this.textBlockMessage.Text = "Exception:\n" + exception.Message;
35 | this.exception = exception;
36 | this.copyTimer.Elapsed += OnCopyTimer;
37 | this.copyTimer.AutoReset = false;
38 | this.copyText = buttonCopy.Content as string;
39 | if (alwaysContinue) {
40 | this.buttonExit.Visibility = Visibility.Collapsed;
41 | this.buttonContinue.IsDefault = true;
42 | }
43 | }
44 | /**Constructs the error message box with an exception object.*/
45 | public ErrorMessageBox(object exceptionObject, bool alwaysContinue) {
46 | InitializeComponent();
47 |
48 | this.textBlockMessage.Text = "Exception:\n" + (exceptionObject is Exception ? (exceptionObject as Exception).Message : exceptionObject.ToString());
49 | this.exception = (exceptionObject is Exception ? exceptionObject as Exception : null);
50 | this.exceptionObject = (exceptionObject is Exception ? null : exceptionObject);
51 | this.copyTimer.Elapsed += OnCopyTimer;
52 | this.copyTimer.AutoReset = false;
53 | this.copyText = buttonCopy.Content as string;
54 | if (!(exceptionObject is Exception)) {
55 | this.buttonException.IsEnabled = false;
56 | }
57 | if (alwaysContinue) {
58 | this.buttonExit.Visibility = Visibility.Collapsed;
59 | this.buttonContinue.IsDefault = true;
60 | }
61 | }
62 |
63 |
64 | #endregion
65 | //============ EVENTS ============
66 | #region Events
67 |
68 | private void OnWindowClosing(object sender, System.ComponentModel.CancelEventArgs e) {
69 | copyTimer.Stop();
70 | }
71 | private void OnExit(object sender, RoutedEventArgs e) {
72 | DialogResult = true;
73 | Close();
74 | }
75 | private void OnCopyTimer(object sender, ElapsedEventArgs e) {
76 | Dispatcher.Invoke(() => {
77 | buttonCopy.Content = copyText;
78 | });
79 | }
80 | private void OnCopyToClipboard(object sender, RoutedEventArgs e) {
81 | Clipboard.SetText(exception != null ? exception.ToString() : exceptionObject.ToString());
82 | buttonCopy.Content = "Exception Copied!";
83 | copyTimer.Stop();
84 | copyTimer.Start();
85 | }
86 | private void OnSeeFullException(object sender, RoutedEventArgs e) {
87 | viewingFull = !viewingFull;
88 | if (!viewingFull) {
89 | buttonException.Content = "See Full Exception";
90 | textBlockMessage.Text = "Exception:\n" + exception.Message;
91 | clientArea.Height = 230;
92 | scrollViewer.ScrollToTop();
93 | }
94 | else {
95 | buttonException.Content = "Hide Full Exception";
96 | // Size may not be changed yet so just incase we also have OnMessageSizeChanged
97 | textBlockMessage.Text = "Exception:\n" + exception.ToString();
98 | clientArea.Height = Math.Min(480, Math.Max(230, textBlockMessage.ActualHeight + 102));
99 | scrollViewer.ScrollToTop();
100 | }
101 | }
102 | private void OnMessageSizeChanged(object sender, SizeChangedEventArgs e) {
103 | if (viewingFull) {
104 | clientArea.Height = Math.Min(480, Math.Max(230, textBlockMessage.ActualHeight + 102));
105 | scrollViewer.ScrollToTop();
106 | }
107 | }
108 | private void OnPreviewKeyDown(object sender, KeyEventArgs e) {
109 | var focused = FocusManager.GetFocusedElement(this);
110 | switch (e.Key) {
111 | case Key.Right:
112 | if (focused == buttonContinue && buttonExit.Visibility == Visibility.Visible)
113 | buttonExit.Focus();
114 | else if (focused == buttonCopy)
115 | buttonContinue.Focus();
116 | else if (focused == buttonException)
117 | buttonCopy.Focus();
118 | e.Handled = true;
119 | break;
120 | case Key.Left:
121 | if (focused == null) {
122 | if (buttonExit.Visibility == Visibility.Visible)
123 | buttonContinue.Focus();
124 | else
125 | buttonCopy.Focus();
126 | }
127 | else if (focused == buttonExit)
128 | buttonContinue.Focus();
129 | else if (focused == buttonContinue)
130 | buttonCopy.Focus();
131 | else if (focused == buttonCopy && buttonException.IsEnabled)
132 | buttonException.Focus();
133 | e.Handled = true;
134 | break;
135 | }
136 | }
137 | private void OnRequestNavigate(object sender, RequestNavigateEventArgs e) {
138 | Process.Start((sender as Hyperlink).NavigateUri.ToString());
139 | }
140 |
141 | #endregion
142 | //=========== SHOWING ============
143 | #region Showing
144 |
145 | /**Shows an error message box with an exception.*/
146 | public static bool Show(Exception exception, bool alwaysContinue = false) {
147 | ErrorMessageBox messageBox = new ErrorMessageBox(exception, alwaysContinue);
148 | var result = messageBox.ShowDialog();
149 | return result.HasValue && result.Value;
150 | }
151 | /**Shows an error message box with an exception object.*/
152 | public static bool Show(object exceptionObject, bool alwaysContinue = false) {
153 | ErrorMessageBox messageBox = new ErrorMessageBox(exceptionObject, alwaysContinue);
154 | var result = messageBox.ShowDialog();
155 | return result.HasValue && result.Value;
156 | }
157 |
158 | #endregion
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/FolderBrowserLauncher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 | using System.Windows.Forms;
5 | using System.Windows.Interop;
6 |
7 | namespace QuickWaveBank.Windows {
8 | //https://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dialog-does-not-scroll-to-selected-folder
9 | /**Launch a folder browser and make sure it scrolls to the selected folder open opening.*/
10 | public static class FolderBrowserLauncher {
11 | ///
12 | /// Using title text to look for the top level dialog window is fragile.
13 | /// In particular, this will fail in non-English applications.
14 | ///
15 | const string _topLevelSearchString = "Browse For Folder";
16 |
17 | ///
18 | /// These should be more robust. We find the correct child controls in the dialog
19 | /// by using the GetDlgItem method, rather than the FindWindow(Ex) method,
20 | /// because the dialog item IDs should be constant.
21 | ///
22 | const int _dlgItemBrowseControl = 0;
23 | const int _dlgItemTreeView = 100;
24 |
25 | [DllImport("user32.dll", SetLastError = true)]
26 | static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
27 |
28 | [DllImport("user32.dll")]
29 | static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
30 |
31 | [DllImport("user32.dll", CharSet = CharSet.Auto)]
32 | static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
33 |
34 | ///
35 | /// Some of the messages that the Tree View control will respond to
36 | ///
37 | private const int TV_FIRST = 0x1100;
38 | private const int TVM_SELECTITEM = (TV_FIRST + 11);
39 | private const int TVM_GETNEXTITEM = (TV_FIRST + 10);
40 | private const int TVM_GETITEM = (TV_FIRST + 12);
41 | private const int TVM_ENSUREVISIBLE = (TV_FIRST + 20);
42 |
43 | ///
44 | /// Constants used to identity specific items in the Tree View control
45 | ///
46 | private const int TVGN_ROOT = 0x0;
47 | private const int TVGN_NEXT = 0x1;
48 | private const int TVGN_CHILD = 0x4;
49 | private const int TVGN_FIRSTVISIBLE = 0x5;
50 | private const int TVGN_NEXTVISIBLE = 0x6;
51 | private const int TVGN_CARET = 0x9;
52 |
53 | ///
54 | /// Calling this method is identical to calling the ShowDialog method of the provided
55 | /// FolderBrowserDialog, except that an attempt will be made to scroll the Tree View
56 | /// to make the currently selected folder visible in the dialog window.
57 | ///
58 | ///
59 | ///
60 | ///
61 | public static bool? ShowFolderBrowser(this FolderBrowserDialog dlg, Window owner = null) {
62 | DialogResult result = DialogResult.Cancel;
63 | int retries = 40;
64 | NativeWindow parent = null;
65 | if (owner != null) {
66 | parent = new NativeWindow();
67 | parent.AssignHandle(new WindowInteropHelper(owner).Handle);
68 | }
69 | try {
70 | if (dlg.SelectedPath != "")
71 | dlg.SelectedPath = System.IO.Path.GetFullPath(dlg.SelectedPath);
72 | }
73 | catch { }
74 |
75 | using (Timer t = new Timer()) {
76 | t.Tick += (s, a) => {
77 | if (retries > 0) {
78 | --retries;
79 | IntPtr hwndDlg = FindWindow((string)null, _topLevelSearchString);
80 | if (hwndDlg != IntPtr.Zero) {
81 | IntPtr hwndFolderCtrl = GetDlgItem(hwndDlg, _dlgItemBrowseControl);
82 | if (hwndFolderCtrl != IntPtr.Zero) {
83 | IntPtr hwndTV = GetDlgItem(hwndFolderCtrl, _dlgItemTreeView);
84 |
85 | if (hwndTV != IntPtr.Zero) {
86 | IntPtr item = SendMessage(hwndTV, (uint)TVM_GETNEXTITEM, new IntPtr(TVGN_CARET), IntPtr.Zero);
87 | if (item != IntPtr.Zero) {
88 | // Let's send this 40 times until we drill it into the folder browser's thick skull.
89 | // Otherwise it will just go back to the beginning.
90 | SendMessage(hwndTV, TVM_ENSUREVISIBLE, IntPtr.Zero, item);
91 | //retries = 0;
92 | //t.Stop();
93 | }
94 | }
95 | }
96 | }
97 | }
98 |
99 | else {
100 | //
101 | // We failed to find the Tree View control.
102 | //
103 | // As a fall back (and this is an UberUgly hack), we will send
104 | // some fake keystrokes to the application in an attempt to force
105 | // the Tree View to scroll to the selected item.
106 | //
107 | t.Stop();
108 | //SendKeys.Send("{TAB}{TAB}{DOWN}{DOWN}{UP}{UP}");
109 | }
110 | };
111 |
112 | t.Interval = 10;
113 | t.Start();
114 |
115 | result = dlg.ShowDialog(parent);
116 | };
117 |
118 | return (result == DialogResult.OK);
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/TriggerMessageBox.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/TriggerMessageBox.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Media;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 | using System.Windows.Input;
6 | using System.Windows.Media.Imaging;
7 |
8 | namespace QuickWaveBank.Windows {
9 | /**The different types of icons available for message boxes.*/
10 | public enum MessageIcon {
11 | /**A blue (i) icon.*/
12 | Info,
13 | /**A blue (?) icon.*/
14 | Question,
15 | /**A yellow /!\ icon.*/
16 | Warning,
17 | /**A red (!) icon.*/
18 | Error
19 | }
20 |
21 | /**A custom message box that doesn't look like shite.*/
22 | public partial class TriggerMessageBox : Window {
23 | //=========== MEMBERS ============
24 | #region Members
25 |
26 | /**The result of from pressing one of the message box buttons.*/
27 | private MessageBoxResult result;
28 | /**The minimum width of the message box.*/
29 | private int minWidth;
30 | /**The message box buttons setup.*/
31 | private MessageBoxButton buttons;
32 | /**The icon of the message.*/
33 | private MessageIcon icon;
34 |
35 | #endregion
36 | //========= CONSTRUCTORS =========
37 | #region Constructors
38 |
39 | /**Constructs and sets up the message box.*/
40 | private TriggerMessageBox(MessageIcon icon, string title, string message, MessageBoxButton buttons, string buttonName1 = null, string buttonName2 = null, string buttonName3 = null) {
41 | InitializeComponent();
42 | this.buttons = buttons;
43 | this.icon = icon;
44 | this.minWidth = 280;
45 |
46 | #region Load Message Icons
47 | switch (icon) {
48 | case MessageIcon.Info:
49 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/InfoIcon.png"));
50 | break;
51 | case MessageIcon.Question:
52 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/QuestionIcon.png"));
53 | break;
54 | case MessageIcon.Warning:
55 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/WarningIcon.png"));
56 | break;
57 | case MessageIcon.Error:
58 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/ErrorIcon.png"));
59 | break;
60 | }
61 | #endregion
62 |
63 | // Setup the buttons
64 | switch (buttons) {
65 | #region MessageBoxButton.OK
66 | case MessageBoxButton.OK:
67 | button1.IsDefault = true;
68 | button1.Content = "OK";
69 | button1.Tag = MessageBoxResult.OK;
70 | button2.Visibility = Visibility.Collapsed;
71 | button3.Visibility = Visibility.Collapsed;
72 | minWidth -= 85 * 2;
73 | result = MessageBoxResult.OK;
74 | if (buttonName1 != null)
75 | button1.Content = buttonName1;
76 | break;
77 | #endregion
78 | #region MessageBoxButton.OKCancel
79 | case MessageBoxButton.OKCancel:
80 | button1.IsDefault = true;
81 | button1.Content = "OK";
82 | button1.Tag = MessageBoxResult.OK;
83 | button2.IsCancel = true;
84 | button2.Content = "Cancel";
85 | button2.Tag = MessageBoxResult.Cancel;
86 | button3.Visibility = Visibility.Collapsed;
87 | minWidth -= 85;
88 | result = MessageBoxResult.Cancel;
89 | if (buttonName1 != null)
90 | button1.Content = buttonName1;
91 | if (buttonName2 != null)
92 | button2.Content = buttonName2;
93 | break;
94 | #endregion
95 | #region MessageBoxButton.YesNo
96 | case MessageBoxButton.YesNo:
97 | button1.IsDefault = true;
98 | button1.Content = "Yes";
99 | button1.Tag = MessageBoxResult.Yes;
100 | button2.IsCancel = true;
101 | button2.Content = "No";
102 | button2.Tag = MessageBoxResult.No;
103 | button3.Visibility = Visibility.Collapsed;
104 | minWidth -= 85;
105 | result = MessageBoxResult.No;
106 | if (buttonName1 != null)
107 | button1.Content = buttonName1;
108 | if (buttonName2 != null)
109 | button2.Content = buttonName2;
110 | break;
111 | #endregion
112 | #region MessageBoxButton.YesNoCancel
113 | case MessageBoxButton.YesNoCancel:
114 | button1.IsDefault = true;
115 | button1.Content = "Yes";
116 | button1.Tag = MessageBoxResult.Yes;
117 | button2.Content = "No";
118 | button2.Tag = MessageBoxResult.No;
119 | button3.IsCancel = true;
120 | button3.Content = "Cancel";
121 | button3.Tag = MessageBoxResult.Cancel;
122 | result = MessageBoxResult.Cancel;
123 | if (buttonName1 != null)
124 | button1.Content = buttonName1;
125 | if (buttonName2 != null)
126 | button2.Content = buttonName2;
127 | if (buttonName3 != null)
128 | button3.Content = buttonName3;
129 | break;
130 | #endregion
131 | }
132 |
133 | this.Title = title;
134 | this.textBlockMessage.Text = message;
135 | }
136 |
137 | #endregion
138 | //=========== HELPERS ============
139 | #region Helpers
140 |
141 | /**Gets the number of message box buttons.*/
142 | private int ButtonCount {
143 | get {
144 | switch (buttons) {
145 | case MessageBoxButton.OK:
146 | return 1;
147 | case MessageBoxButton.OKCancel:
148 | case MessageBoxButton.YesNo:
149 | return 2;
150 | case MessageBoxButton.YesNoCancel:
151 | return 3;
152 | }
153 | return 3;
154 | }
155 | }
156 | /**Gets the button at the specified index.*/
157 | private Button GetButtonAt(int index) {
158 | switch (index) {
159 | case 0: return button1;
160 | case 1: return button2;
161 | case 2: return button3;
162 | }
163 | return null;
164 | }
165 | /**Gets the index of the button.*/
166 | private int IndexOfButton(Button button) {
167 | if (button == button1)
168 | return 0;
169 | else if (button == button2)
170 | return 1;
171 | else if (button == button3)
172 | return 2;
173 | return -1;
174 | }
175 |
176 | #endregion
177 | //============ EVENTS ============
178 | #region Events
179 |
180 | private void OnWindowLoaded(object sender, RoutedEventArgs e) {
181 | clientArea.Width = Math.Max(minWidth, Math.Max(textBlockMessage.ActualWidth + 60, stackPanelButtons.ActualWidth + 10));
182 | clientArea.Height += textBlockMessage.ActualHeight - 16;
183 |
184 | #region Load Message Sounds
185 | switch (icon) {
186 | case MessageIcon.Info: SystemSounds.Asterisk.Play(); break;
187 | case MessageIcon.Question: SystemSounds.Asterisk.Play(); break;
188 | case MessageIcon.Warning: SystemSounds.Exclamation.Play(); break;
189 | case MessageIcon.Error: SystemSounds.Hand.Play(); break;
190 | }
191 | #endregion
192 | }
193 | private void OnButtonClicked(object sender, RoutedEventArgs e) {
194 | result = (MessageBoxResult)((Button)sender).Tag;
195 | Close();
196 | }
197 | private void OnPreviewKeyDown(object sender, KeyEventArgs e) {
198 | var button = FocusManager.GetFocusedElement(this) as Button;
199 | switch (e.Key) {
200 | case Key.Right:
201 | if (button == null && ButtonCount > 1)
202 | GetButtonAt(1).Focus();
203 | else if (button != null && IndexOfButton(button) < ButtonCount - 1)
204 | button.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
205 | e.Handled = true;
206 | break;
207 | case Key.Left:
208 | if (button != null && IndexOfButton(button) > 0)
209 | button.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
210 | e.Handled = true;
211 | break;
212 | }
213 | }
214 |
215 | #endregion
216 | //=========== SHOWING ============
217 | #region Showing
218 |
219 | /**Shows the message box.*/
220 | public static MessageBoxResult Show(Window window, MessageIcon icon, string message) {
221 | return Show(window, icon, message, "", MessageBoxButton.OK);
222 | }
223 | /**Shows the message box.*/
224 | public static MessageBoxResult Show(Window window, MessageIcon icon, string message, string title) {
225 | return Show(window, icon, message, title, MessageBoxButton.OK);
226 | }
227 | /**Shows the message box.*/
228 | public static MessageBoxResult Show(Window window, MessageIcon icon, string message, MessageBoxButton buttons) {
229 | return Show(window, icon, message, "", buttons);
230 | }
231 | /**Shows the message box.*/
232 | public static MessageBoxResult Show(Window window, MessageIcon icon, string message, string title, MessageBoxButton buttons, string buttonName1 = null, string buttonName2 = null, string buttonName3 = null) {
233 | TriggerMessageBox messageBox = new TriggerMessageBox(icon, title, message, buttons, buttonName1, buttonName2, buttonName3);
234 | if (window == null || window.Visibility != Visibility.Visible)
235 | messageBox.WindowStartupLocation = WindowStartupLocation.CenterScreen;
236 | else
237 | messageBox.Owner = window;
238 | messageBox.ShowDialog();
239 | return messageBox.result;
240 | }
241 |
242 | #endregion
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/VolumeDialog.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/QuickWaveBank/Windows/VolumeDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace QuickWaveBank.Windows {
16 | ///
17 | /// Interaction logic for VolumeDialog.xaml
18 | ///
19 | public partial class VolumeDialog : Window {
20 | private Action volumeCallback;
21 | private bool loaded = false;
22 |
23 | public VolumeDialog(Action volumeCallback) {
24 | InitializeComponent();
25 | this.volumeCallback = volumeCallback;
26 | sliderVolume.Value = Config.Volume * 100.0;
27 | checkboxMuted.IsChecked = Config.Muted;
28 | labelVolume.Content = "Volume: " + ((int)(Config.Volume * 100)).ToString() + "%";
29 | UpdateIcon();
30 | }
31 |
32 | public static void Show(Window owner, Action volumeCallback) {
33 | VolumeDialog dialog = new VolumeDialog(volumeCallback);
34 | dialog.Owner = owner;
35 | dialog.ShowDialog();
36 | }
37 |
38 | private void OnMuteChecked(object sender, RoutedEventArgs e) {
39 | if (!loaded)
40 | return;
41 | Config.Muted = checkboxMuted.IsChecked.Value;
42 | UpdateIcon();
43 | volumeCallback?.Invoke();
44 | }
45 |
46 | private void OnVolumeChanged(object sender, RoutedPropertyChangedEventArgs e) {
47 | if (!loaded)
48 | return;
49 | Config.Volume = sliderVolume.Value / 100.0;
50 | labelVolume.Content = "Volume: " + ((int)(Config.Volume * 100)).ToString() + "%";
51 | UpdateIcon();
52 | volumeCallback?.Invoke();
53 | }
54 |
55 | private void OnOKClicked(object sender, RoutedEventArgs e) {
56 | Close();
57 | }
58 |
59 | private void UpdateIcon() {
60 | if (Config.Muted)
61 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/VolumeMute.png"));
62 | else if (Config.Volume == 0.0)
63 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/VolumeNone.png"));
64 | else if (Config.Volume < 0.5)
65 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/VolumeLow.png"));
66 | else
67 | this.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons/VolumeHigh.png"));
68 | }
69 |
70 | private void OnWindowLoaded(object sender, RoutedEventArgs e) {
71 | loaded = true;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/QuickWaveBank/Xap/XapFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using QuickWaveBank.Util;
8 |
9 | namespace QuickWaveBank.Xap {
10 | /**An Xact3 Xap project file.*/
11 | public class XapFile {
12 | //========== CONSTANTS ===========
13 | #region Constants
14 |
15 | /**The characters reserved in Xap files.*/
16 | public static readonly char[] FormatCharacters = {
17 | '{', '}', ';', '='
18 | };
19 |
20 | #endregion
21 | //=========== MEMBERS ============
22 | #region Members
23 |
24 | /**The root group.*/
25 | public XapGroup Root { get; private set; }
26 | /**True if spaces are used instead of tabs.*/
27 | public bool UseSpaces { get; set; }
28 |
29 | #endregion
30 | //========= CONSTRUCTORS =========
31 | #region Constructors
32 |
33 | /**Constructs the xap file.*/
34 | public XapFile() {
35 | Root = new XapGroup("");
36 | UseSpaces = false;
37 | }
38 |
39 | #endregion
40 | //=========== LOADING ============
41 | #region Loading
42 |
43 | /**Loads the Xap file from the filepath.*/
44 | public void Load(string filepath) {
45 | Root.Clear();
46 | var stream = new FileStream(filepath, FileMode.Open);
47 | Load(stream);
48 | stream.Close();
49 | }
50 | /**Loads the Xap file from the stream.*/
51 | public void Load(Stream stream) {
52 | Root.Clear();
53 | StreamReader reader = new StreamReader(stream);
54 | Parse(reader);
55 | }
56 | /**Saves the Xap file to the filepath.*/
57 | public void Save(string filepath) {
58 | var stream = new FileStream(filepath, FileMode.OpenOrCreate);
59 | Save(stream);
60 | stream.Close();
61 | }
62 | /**Saves the Xap file to the stream.*/
63 | public void Save(Stream stream) {
64 | stream.SetLength(0);
65 | StreamWriter writer = new StreamWriter(stream);
66 | Write(writer);
67 | writer.Flush();
68 | }
69 |
70 | #endregion
71 | //=========== PARSING ============
72 | #region Parsing
73 |
74 | /**Parses the Xap file.*/
75 | private void Parse(StreamReader reader) {
76 | string[] tokens = ReadTokens(reader);
77 | int index = 0;
78 | Root = ParseGroup(tokens, ref index, "");
79 | }
80 | /**Parses a group.*/
81 | private XapGroup ParseGroup(string[] tokens, ref int index, string name) {
82 | XapGroup group = new XapGroup(name);
83 | string currentText = null;
84 | string variableName = null;
85 | for (; index < tokens.Length; index++) {
86 | if (IsFormatCharacter(tokens[index].First())) {
87 | switch (tokens[index].First()) {
88 | case '=':
89 | if (variableName != null)
90 | throw new ArgumentException("Invalid token '='. Variable name already declared.");
91 | if (currentText != null)
92 | variableName = currentText;
93 | else
94 | throw new ArgumentException("Invalid token '='. No variable name.");
95 | break;
96 | case ';':
97 | if (variableName != null) {
98 | if (currentText != null) {
99 | group.AddVariable(variableName, currentText);
100 | variableName = null;
101 | }
102 | else
103 | throw new ArgumentException("Invalid token ';'. No variable value.");
104 | }
105 | else {
106 | throw new ArgumentException("Invalid token ';'. No variable name or value.");
107 | }
108 | break;
109 | case '{':
110 | if (variableName != null) {
111 | throw new ArgumentException(
112 | "Invalid token '{'. " + (currentText == null ?
113 | "Expected variable value." :
114 | "Expected ';'.")
115 | );
116 | }
117 | else {
118 | if (currentText != null) {
119 | index++;
120 | group.AddGroup(ParseGroup(tokens, ref index, currentText));
121 | }
122 | else
123 | throw new ArgumentException("Invalid token '{'. No group name.");
124 | }
125 | break;
126 | case '}':
127 | if (variableName != null) {
128 | throw new ArgumentException(
129 | "Unexpected end of group. " + (currentText == null ?
130 | "Expected variable value." :
131 | "Expected ';'.")
132 | );
133 | }
134 | else if (currentText != null) {
135 | throw new ArgumentException("Unexpected end of group. Leftover text.");
136 | }
137 | else if (name == "")
138 | throw new ArgumentException("Invalid token '}'. Not in group.");
139 | else
140 | return group;
141 | }
142 | currentText = null;
143 | }
144 | else {
145 | currentText = tokens[index];
146 | }
147 | }
148 | if (variableName != null) {
149 | throw new ArgumentException(
150 | "Unexpected end of file. " + (currentText == null ?
151 | "Expected variable value." :
152 | "Expected ';'.")
153 | );
154 | }
155 | else if (currentText != null) {
156 | throw new ArgumentException("Unexpected end of file. Leftover text.");
157 | }
158 | else if (name != "") {
159 | throw new ArgumentException("Unexpected end of file. Expected '}'.");
160 | }
161 | return group;
162 | }
163 | /**Splits up the Xap file into tokens to read.*/
164 | private string[] ReadTokens(StreamReader reader) {
165 | char[] buffer = new char[1024];
166 | int charsRead = reader.Read(buffer, 0, buffer.Length);
167 | string text = new string(buffer).Substring(0, charsRead);
168 | List tokens = new List();
169 | string token;
170 | for (int i = 0; i < text.Length; i++) {
171 | char c = text[i];
172 | if (IsFormatCharacter(c)) {
173 | token = text.Substring(0, i).Trim();
174 | if (token.Length > 0)
175 | tokens.Add(token);
176 | tokens.Add(new string(c, 1));
177 | text = text.Substring(i + 1);
178 | i = -1;
179 | }
180 | if (i + 1 == text.Length) {
181 | charsRead = reader.Read(buffer, 0, buffer.Length);
182 | text += new string(buffer).Substring(0, charsRead);
183 | }
184 | }
185 |
186 | token = text.Trim();
187 | if (token.Length > 0)
188 | tokens.Add(token);
189 |
190 | return tokens.ToArray();
191 | }
192 |
193 | #endregion
194 | //=========== WRITING ============
195 | #region Writing
196 |
197 | /**Writes the Xap file to the stream.*/
198 | private void Write(StreamWriter writer) {
199 | WriteGroup(Root, writer);
200 | }
201 | /**Writes the Xap group to the stream.*/
202 | private void WriteGroup(XapGroup currentGroup, StreamWriter writer, int depth = 0) {
203 | foreach (XapVariable variable in currentGroup.Variables) {
204 | writer.WriteLine(GetTab(depth) + variable.Name + " = " + variable.Value + ";");
205 | }
206 | if (currentGroup.Variables.Count > 0 && currentGroup.Groups.Count > 0)
207 | writer.WriteLine();
208 | bool first = true;
209 | foreach (XapGroup group in currentGroup.Groups) {
210 | if (!first) writer.WriteLine();
211 | else first = false;
212 |
213 | writer.WriteLine(GetTab(depth) + group.Name);
214 | writer.WriteLine(GetTab(depth) + "{");
215 | WriteGroup(group, writer, depth + 1);
216 | writer.WriteLine(GetTab(depth) + "}");
217 | }
218 | }
219 | /**Gets indentation based on the tabs setting.*/
220 | private string GetTab(int depth) {
221 | if (UseSpaces)
222 | return new string(' ', depth * 4);
223 | else
224 | return new string('\t', depth);
225 | }
226 |
227 | #endregion
228 | //============ STATIC ============
229 | #region Static
230 |
231 | /**Gets if the string contains any format characters.*/
232 | public static bool ContainsFormatCharacter(string s) {
233 | foreach (char c in s) {
234 | if (IsFormatCharacter(c))
235 | return true;
236 | }
237 | return false;
238 | }
239 | /*public static string RemoveFormatCharacters(string s) {
240 | foreach (char specialChar in FormatCharacters) {
241 | s = s.Replace(new string(specialChar, 1), "");
242 | }
243 | return s;
244 | }*/
245 | public static string SanitizeString(string s, string replaceCharsWith, bool escapeControl, bool escapeUnicode, bool escapeBackslash) {
246 | StringBuilder sanitized = new StringBuilder(s);
247 | SanitizeString(sanitized, replaceCharsWith, escapeControl, escapeUnicode, escapeBackslash);
248 | return sanitized.ToString();
249 | }
250 | public static StringBuilder SanitizeString(StringBuilder sanitized, string replaceCharsWith, bool escapeControl, bool escapeUnicode, bool escapeBackslash) {
251 | // Escape backslashes before potentially inserting more
252 | if (escapeBackslash) {
253 | sanitized.Replace("\\", "\\\\");
254 | }
255 |
256 | // Sanitize Xap reserved characters
257 | foreach (char specialChar in FormatCharacters) {
258 | sanitized.Replace(new string(specialChar, 1), replaceCharsWith);
259 | }
260 |
261 | // Handle Xap illegal control characters
262 | if (escapeControl) {
263 | sanitized.Replace("\n", "\\n").Replace("\r", "\\r")
264 | .Replace("\a", "\\a").Replace("\b", "\\b")
265 | .Replace("\0", "\\0");
266 | }
267 | //else {} // handled in for loop
268 |
269 | // Handle remaining control+Unicode characters
270 | for (int i = 0; i < sanitized.Length; i++) {
271 | char c = sanitized[i];
272 | string replaced = null;
273 | if (c < (char)0x20 || c == (char)0x7f) { // control
274 | if (escapeControl)
275 | replaced = string.Format("\\x{0:x2}", (int)c);
276 | else
277 | replaced = replaceCharsWith;
278 | }
279 | else if (sanitized[i] >= (char)0x80) {// non-ascii
280 | if (escapeUnicode)
281 | replaced = string.Format("\\u{0:x4}", (int)c);
282 | else
283 | replaced = replaceCharsWith;
284 | }
285 |
286 | if (replaced != null) { // do we need to replace?
287 | sanitized.Remove(i, 1);
288 | sanitized.Insert(i, replaced);
289 | i += replaced.Length - 1; // -1 for removed [i]
290 | }
291 | }
292 |
293 | return sanitized;
294 | }
295 | /**Gets if the character is a format character.*/
296 | public static bool IsFormatCharacter(char c) {
297 | foreach (char specialChar in FormatCharacters) {
298 | if (c == specialChar)
299 | return true;
300 | }
301 | return false;
302 | }
303 |
304 | #endregion
305 | }
306 | }
307 |
--------------------------------------------------------------------------------
/QuickWaveBank/Xap/XapGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace QuickWaveBank.Xap {
8 | /**A group used in Xact3 Xap project files.*/
9 | public class XapGroup {
10 | //=========== MEMBERS ============
11 | #region Members
12 |
13 | /**The name of the Xap group.*/
14 | public string Name { get; private set; }
15 | /**The collection of variables in the group.*/
16 | public List Variables { get; private set; }
17 | /**The list of sub-groups in the group.*/
18 | public List Groups { get; private set; }
19 |
20 | #endregion
21 | //========= CONSTRUCTORS =========
22 | #region Constructors
23 |
24 | /**Constructs an Xap group with a name.*/
25 | public XapGroup(string name) {
26 | Name = name;
27 | Variables = new List();
28 | Groups = new List();
29 | }
30 |
31 | #endregion
32 | //========== VARIABLES ===========
33 | #region Variables
34 |
35 | /**adds a variable.*/
36 | public void AddVariable(XapVariable variable) {
37 | Variables.Add(variable);
38 | }
39 | /**Sets or adds a variable.*/
40 | public void AddVariable(string name, string value) {
41 | Variables.Add(new XapVariable(name, value));
42 | }
43 | /**Sets or adds a variable.*/
44 | public void SetVariable(string name, string value, int index = 0) {
45 | Variables.Find((XapVariable v) => {
46 | if (v.Name == name) {
47 | if (index == 0)
48 | return true;
49 | index--;
50 | }
51 | return false;
52 | }).Value = value;
53 | }
54 | /**Removes a variable.*/
55 | public void RemoveVariable(string name, int index = 0) {
56 | Variables.RemoveAt(Variables.FindIndex((XapVariable v) => {
57 | if (v.Name == name) {
58 | if (index == 0)
59 | return true;
60 | index--;
61 | }
62 | return false;
63 | }));
64 | }
65 | /**Removes a variable.*/
66 | public void RemoveVariables(string name) {
67 | int index = Variables.FindIndex((XapVariable v) => { return v.Name == name; });
68 | while (index != -1) {
69 | Variables.RemoveAt(index);
70 | index = Variables.FindIndex((XapVariable v) => { return v.Name == name; });
71 | }
72 | }
73 | /**Sets or adds a variable.*/
74 | public XapVariable GetVariable(string name, int index = 0) {
75 | return Variables.Find((XapVariable v) => {
76 | if (v.Name == name) {
77 | if (index == 0)
78 | return true;
79 | index--;
80 | }
81 | return false;
82 | });
83 | }
84 | /**Gets all the groups with the specified name.*/
85 | public XapVariable[] GetVariables(string name) {
86 | return Variables.FindAll((XapVariable v) => { return v.Name == name; }).ToArray();
87 | }
88 | /**Checks if a variable exists.*/
89 | public bool VariableExists(string name) {
90 | return Variables.Find((XapVariable v) => { return v.Name == name; }) != null;
91 | }
92 | /**Gets the number of groups with the specified name.*/
93 | public int GetVariableCount(string name) {
94 | return Variables.FindAll((XapVariable v) => { return v.Name == name; }).Count;
95 | }
96 | /**Clears all variables.*/
97 | public void ClearVariables() {
98 | Variables.Clear();
99 | }
100 |
101 | #endregion
102 | //============ GROUPS ============
103 | #region Groups
104 |
105 | /**Adds a group.*/
106 | public void AddGroup(string name) {
107 | Groups.Add(new XapGroup(name));
108 | }
109 | /**Adds a group.*/
110 | public void AddGroup(XapGroup group) {
111 | Groups.Add(group);
112 | }
113 | /**Removes a group.*/
114 | public void RemoveGroup(string name, int index = 0) {
115 | Groups.RemoveAt(Groups.FindIndex((XapGroup g) => {
116 | if (g.Name == name) {
117 | if (index == 0)
118 | return true;
119 | index--;
120 | }
121 | return false;
122 | }));
123 | }
124 | /**Removes a group.*/
125 | public void RemoveGroups(string name) {
126 | int index = Groups.FindIndex((XapGroup g) => { return g.Name == name; });
127 | while (index != -1) {
128 | Groups.RemoveAt(index);
129 | index = Groups.FindIndex((XapGroup g) => { return g.Name == name; });
130 | }
131 | }
132 | /**Gets the group with the specified name at the specified index.*/
133 | public XapGroup GetGroup(string name, int index = 0) {
134 | return Groups.Find((XapGroup g) => {
135 | if (g.Name == name) {
136 | if (index == 0)
137 | return true;
138 | index--;
139 | }
140 | return false;
141 | });
142 | }
143 | /**Gets all the groups with the specified name.*/
144 | public XapGroup[] GetGroups(string name) {
145 | return Groups.FindAll((XapGroup g) => { return g.Name == name; }).ToArray();
146 | }
147 | /**Checks is the group exists.*/
148 | public bool GroupExists(string name) {
149 | return Groups.Find((XapGroup g) => { return g.Name == name; }) != null;
150 | }
151 | /**Gets the number of groups with the specified name.*/
152 | public int GetGroupCount(string name) {
153 | return Groups.FindAll((XapGroup g) => { return g.Name == name; }).Count;
154 | }
155 | /**Clears all groups.*/
156 | public void ClearGroups() {
157 | Groups.Clear();
158 | }
159 |
160 | #endregion
161 | //============= BOTH =============
162 | #region Groups
163 |
164 | /**Clears all groups and variables.*/
165 | public void Clear() {
166 | Variables.Clear();
167 | Groups.Clear();
168 | }
169 |
170 | #endregion
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/QuickWaveBank/Xap/XapVariable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace QuickWaveBank.Xap {
8 | /**A variable used in Xact3 Xap project files.*/
9 | public class XapVariable {
10 | //=========== MEMBERS ============
11 | #region Members
12 |
13 | /**The name of the Xap variable.*/
14 | public string Name { get; private set; }
15 | /**The value of the Xap variable.*/
16 | public string Value { get; set; }
17 |
18 | #endregion
19 | //========= CONSTRUCTORS =========
20 | #region Constructors
21 |
22 | /**Constructs an Xap variable with a blank value.*/
23 | public XapVariable(string name) {
24 | Name = name;
25 | Value = "";
26 | }
27 | /**Constructs an Xap variable with a value.*/
28 | public XapVariable(string name, string value) {
29 | Name = name;
30 | Value = value;
31 | }
32 |
33 | #endregion
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/QuickWaveBank/document-convert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/document-convert.png
--------------------------------------------------------------------------------
/QuickWaveBank/document-music-playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/document-music-playlist.png
--------------------------------------------------------------------------------
/QuickWaveBank/folder-open-document-music-playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/folder-open-document-music-playlist.png
--------------------------------------------------------------------------------
/QuickWaveBank/music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trigger-segfault/QuickWaveBank/f3bd907c6ea1d3668db62b1585542cc9ee413bb7/QuickWaveBank/music.png
--------------------------------------------------------------------------------
/QuickWaveBank/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Quick Wave Bank 
2 |
3 | [](https://github.com/trigger-death/QuickWaveBank/releases/latest)
4 | [](https://github.com/trigger-death/QuickWaveBank/releases/latest)
5 | [](https://github.com/trigger-death/QuickWaveBank/releases)
6 | [](https://github.com/trigger-death/QuickWaveBank/commit/bf94593dac379d7f182622f2c3b1e73e876f2d95)
7 | [](https://forums.terraria.org/index.php?threads/61813/)
8 | [](https://discord.gg/vB7jUbY)
9 |
10 | A quick and easy tool for creating Xact Wave Banks for use in games like Terraria. Also comes with extraction capabilities. Save lists of wave files for use with Wave Bank creation.
11 |
12 | 
13 |
14 | ### [Wiki](https://github.com/trigger-death/QuickWaveBank/wiki) | [Credits](https://github.com/trigger-death/QuickWaveBank/wiki/Credits) | [Image Album](http://imgur.com/a/9K2vT)
15 |
16 | ### [](https://github.com/trigger-death/QuickWaveBank/releases/latest)
17 |
18 | ## About
19 |
20 | * **Created By:** Robert Jordan
21 | * **Version:** 1.0.3.1
22 | * **Language:** C#, WPF
23 |
24 | ## Requirements for Running
25 | * .NET Framework 4.5.2 | [Offline Installer](https://www.microsoft.com/en-us/download/details.aspx?id=42642) | [Web Installer](https://www.microsoft.com/en-us/download/details.aspx?id=42643)
26 | * Windows 7 or later
27 |
28 | ## Requirements for Source Code
29 | * Extended.Wpf.Toolkit | [NuGet Package](https://www.nuget.org/packages/Extended.Wpf.Toolkit/)
30 | * Place *XactBld3.exe* from XNA Game Studio 4.0 in QuickWaveBank's Resources folder.
31 | * BuildConsole must be manually rebuilt after changes since it's only linked to QuickWaveBank by resource.
32 |
33 | ## Features
34 | * Create Wave Banks from wave files for use in games like Terraria.
35 | * Load and save wave file lists for later use.
36 | * Extract Wave Banks to facilitate modification.
37 | * No hassle. Visual Studio not required.
38 |
--------------------------------------------------------------------------------