mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 16:19:43 +02:00
Fix mac build. No standard headers in Audacity.h.
This commit is contained in:
parent
7aee5d09d8
commit
0c9deb398c
177
src/Audacity.h
177
src/Audacity.h
@ -170,9 +170,6 @@ void QuitAudacity();
|
||||
// Marks strings for extraction only...must use wxGetTranslation() to translate.
|
||||
#define XO(s) wxT(s)
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
// This renames a good use of this C++ keyword that we don't need to review when hunting for leaks.
|
||||
#define PROHIBITED = delete
|
||||
|
||||
@ -182,178 +179,4 @@ void QuitAudacity();
|
||||
// pointer like std::unique_ptr or std::shared_ptr.
|
||||
#define safenew new
|
||||
|
||||
#if !defined(__WXMSW__)
|
||||
/* replicate the very useful C++14 make_unique for those build environments
|
||||
that don't implement it yet.
|
||||
|
||||
typical useage:
|
||||
|
||||
auto p = std::make_unique<Myclass>(ctorArg1, ctorArg2, ... ctorArgN);
|
||||
p->DoSomething();
|
||||
auto q = std::make_unique<Myclass[]>(count);
|
||||
q[0].DoSomethingElse();
|
||||
|
||||
The first hides naked NEW and DELETE from the source code.
|
||||
The second hides NEW[] and DELETE[]. Both of course ensure destruction if
|
||||
you don't use something like std::move(p) or q.release(). Both expressions require
|
||||
that you identify the type only once, which is brief and less error prone.
|
||||
|
||||
(Whereas this omission of [] might invite a runtime error:
|
||||
std::unique_ptr<Myclass> q { new Myclass[count] }; )
|
||||
|
||||
Some C++11 tricks needed here are (1) variadic argument lists and
|
||||
(2) making the compile-time dispatch work correctly. You can't have
|
||||
a partially specialized template function, but you get the effect of that
|
||||
by other metaprogramming means.
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
// For overloading resolution
|
||||
template <typename X> struct __make_unique_result {
|
||||
using scalar_case = unique_ptr<X>;
|
||||
};
|
||||
|
||||
// Partial specialization of the struct for array case
|
||||
template <typename X> struct __make_unique_result<X[]> {
|
||||
using array_case = unique_ptr<X[]>;
|
||||
using element = X;
|
||||
};
|
||||
|
||||
// Now the scalar version of unique_ptr
|
||||
template<typename X, typename... Args> inline
|
||||
typename __make_unique_result<X>::scalar_case
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
return typename __make_unique_result<X>::scalar_case
|
||||
{ safenew X( forward<Args>(args)... ) };
|
||||
}
|
||||
|
||||
// Now the array version of unique_ptr
|
||||
// The compile-time dispatch trick is that the non-existence
|
||||
// of the scalar_case type makes the above overload
|
||||
// unavailable when the template parameter is explicit
|
||||
template<typename X> inline
|
||||
typename __make_unique_result<X>::array_case
|
||||
make_unique(size_t count)
|
||||
{
|
||||
return typename __make_unique_result<X>::array_case
|
||||
{ safenew typename __make_unique_result<X>::element[count] };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* template class Maybe<X>
|
||||
* Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
|
||||
* You might also use it as a member.
|
||||
* Initialize with create(), then use like a smart pointer,
|
||||
* with *, ->, get(), reset(), or in if()
|
||||
*/
|
||||
|
||||
template<typename X>
|
||||
class Maybe {
|
||||
public:
|
||||
|
||||
// Construct as NULL
|
||||
Maybe() {}
|
||||
|
||||
// Supply the copy and move, so you might use this as a class member too
|
||||
Maybe(const Maybe &that)
|
||||
{
|
||||
if (that.get())
|
||||
create(*that);
|
||||
}
|
||||
|
||||
Maybe& operator= (const Maybe &that)
|
||||
{
|
||||
if (this != &that) {
|
||||
if (that.get())
|
||||
create(*that);
|
||||
else
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe(Maybe &&that)
|
||||
{
|
||||
if (that.get())
|
||||
create(::std::move(*that));
|
||||
}
|
||||
|
||||
Maybe& operator= (Maybe &&that)
|
||||
{
|
||||
if (this != &that) {
|
||||
if (that.get())
|
||||
create(::std::move(*that));
|
||||
else
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make an object in the buffer, passing constructor arguments,
|
||||
// but destroying any previous object first
|
||||
// Note that if constructor throws, we remain in a consistent
|
||||
// NULL state -- giving exception safety but only weakly
|
||||
// (previous value was lost if present)
|
||||
template<typename... Args>
|
||||
void create(Args... args)
|
||||
{
|
||||
// Lose any old value
|
||||
reset();
|
||||
// Create new value
|
||||
pp = safenew(address()) X( std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
// Destroy any object that was built in it
|
||||
~Maybe()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// Pointer-like operators
|
||||
|
||||
// Dereference, with the usual bad consequences if NULL
|
||||
X &operator* () const
|
||||
{
|
||||
return *pp;
|
||||
}
|
||||
|
||||
X *operator-> () const
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
X* get() const
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (pp)
|
||||
pp->~X(), pp = nullptr;
|
||||
}
|
||||
|
||||
// So you can say if(ptr)
|
||||
explicit operator bool() const
|
||||
{
|
||||
return pp != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
X* address()
|
||||
{
|
||||
return reinterpret_cast<X*>(&storage);
|
||||
}
|
||||
|
||||
// Data
|
||||
typename ::std::aligned_storage<
|
||||
sizeof(X)
|
||||
// , alignof(X) // Not here yet in all compilers
|
||||
>::type storage{};
|
||||
X* pp{ nullptr };
|
||||
};
|
||||
|
||||
#endif // __AUDACITY_H__
|
||||
|
@ -85,6 +85,7 @@
|
||||
#ifdef _DEBUG
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
#undef new
|
||||
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@ out.
|
||||
#include <wx/math.h>
|
||||
|
||||
#include "Internat.h"
|
||||
#include "MemoryX.h"
|
||||
|
||||
// msmeyer: Define this to add debug output via printf()
|
||||
//#define DEBUG_BLOCKFILE
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "DirManager.h"
|
||||
#include "MemoryX.h"
|
||||
|
||||
#include <time.h> // to use time() for srand()
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifndef __AUDACITY_FREQ_WINDOW__
|
||||
#define __AUDACITY_FREQ_WINDOW__
|
||||
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
#include <vector>
|
||||
#include <wx/brush.h>
|
||||
#include <wx/dcmemory.h>
|
||||
|
@ -163,6 +163,7 @@ audacity_SOURCES = \
|
||||
MacroMagic.h \
|
||||
Matrix.cpp \
|
||||
Matrix.h \
|
||||
MemoryX.h \
|
||||
Menus.cpp \
|
||||
Menus.h \
|
||||
Mix.cpp \
|
||||
|
191
src/MemoryX.h
Normal file
191
src/MemoryX.h
Normal file
@ -0,0 +1,191 @@
|
||||
#ifndef __AUDACITY_MEMORY_X_H__
|
||||
#define __AUDACITY_MEMORY_X_H__
|
||||
|
||||
// C++ standard header <memory> with a few extensions
|
||||
#include <memory>
|
||||
|
||||
#if !(defined(__WXMSW__) || defined(__WXMAC__))
|
||||
/* replicate the very useful C++14 make_unique for those build environments
|
||||
that don't implement it yet.
|
||||
typical useage:
|
||||
auto p = std::make_unique<Myclass>(ctorArg1, ctorArg2, ... ctorArgN);
|
||||
p->DoSomething();
|
||||
auto q = std::make_unique<Myclass[]>(count);
|
||||
q[0].DoSomethingElse();
|
||||
|
||||
The first hides naked NEW and DELETE from the source code.
|
||||
The second hides NEW[] and DELETE[]. Both of course ensure destruction if
|
||||
you don't use something like std::move(p) or q.release(). Both expressions require
|
||||
that you identify the type only once, which is brief and less error prone.
|
||||
|
||||
(Whereas this omission of [] might invite a runtime error:
|
||||
std::unique_ptr<Myclass> q { new Myclass[count] }; )
|
||||
|
||||
Some C++11 tricks needed here are (1) variadic argument lists and
|
||||
(2) making the compile-time dispatch work correctly. You can't have
|
||||
a partially specialized template function, but you get the effect of that
|
||||
by other metaprogramming means.
|
||||
*/
|
||||
|
||||
namespace std {
|
||||
// For overloading resolution
|
||||
template <typename X> struct __make_unique_result {
|
||||
using scalar_case = unique_ptr<X>;
|
||||
};
|
||||
|
||||
// Partial specialization of the struct for array case
|
||||
template <typename X> struct __make_unique_result<X[]> {
|
||||
using array_case = unique_ptr<X[]>;
|
||||
using element = X;
|
||||
};
|
||||
|
||||
// Now the scalar version of unique_ptr
|
||||
template<typename X, typename... Args> inline
|
||||
typename __make_unique_result<X>::scalar_case
|
||||
make_unique(Args&&... args)
|
||||
{
|
||||
return typename __make_unique_result<X>::scalar_case
|
||||
{ safenew X(forward<Args>(args)...) };
|
||||
}
|
||||
|
||||
// Now the array version of unique_ptr
|
||||
// The compile-time dispatch trick is that the non-existence
|
||||
// of the scalar_case type makes the above overload
|
||||
// unavailable when the template parameter is explicit
|
||||
template<typename X> inline
|
||||
typename __make_unique_result<X>::array_case
|
||||
make_unique(size_t count)
|
||||
{
|
||||
return typename __make_unique_result<X>::array_case
|
||||
{ safenew typename __make_unique_result<X>::element[count] };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* template class Maybe<X>
|
||||
* Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
|
||||
* You might also use it as a member.
|
||||
* Initialize with create(), then use like a smart pointer,
|
||||
* with *, ->, get(), reset(), or in if()
|
||||
*/
|
||||
|
||||
// Placement-new is used below, and that does not cooperate with the DEBUG_NEW for Visual Studio
|
||||
#undef new
|
||||
|
||||
template<typename X>
|
||||
class Maybe {
|
||||
public:
|
||||
|
||||
// Construct as NULL
|
||||
Maybe() {}
|
||||
|
||||
// Supply the copy and move, so you might use this as a class member too
|
||||
Maybe(const Maybe &that)
|
||||
{
|
||||
if (that.get())
|
||||
create(*that);
|
||||
}
|
||||
|
||||
Maybe& operator= (const Maybe &that)
|
||||
{
|
||||
if (this != &that) {
|
||||
if (that.get())
|
||||
create(*that);
|
||||
else
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Maybe(Maybe &&that)
|
||||
{
|
||||
if (that.get())
|
||||
create(::std::move(*that));
|
||||
}
|
||||
|
||||
Maybe& operator= (Maybe &&that)
|
||||
{
|
||||
if (this != &that) {
|
||||
if (that.get())
|
||||
create(::std::move(*that));
|
||||
else
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Make an object in the buffer, passing constructor arguments,
|
||||
// but destroying any previous object first
|
||||
// Note that if constructor throws, we remain in a consistent
|
||||
// NULL state -- giving exception safety but only weakly
|
||||
// (previous value was lost if present)
|
||||
template<typename... Args>
|
||||
void create(Args... args)
|
||||
{
|
||||
// Lose any old value
|
||||
reset();
|
||||
// Create new value
|
||||
pp = safenew(address()) X(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Destroy any object that was built in it
|
||||
~Maybe()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// Pointer-like operators
|
||||
|
||||
// Dereference, with the usual bad consequences if NULL
|
||||
X &operator* () const
|
||||
{
|
||||
return *pp;
|
||||
}
|
||||
|
||||
X *operator-> () const
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
X* get() const
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (pp)
|
||||
pp->~X(), pp = nullptr;
|
||||
}
|
||||
|
||||
// So you can say if(ptr)
|
||||
explicit operator bool() const
|
||||
{
|
||||
return pp != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
X* address()
|
||||
{
|
||||
return reinterpret_cast<X*>(&storage);
|
||||
}
|
||||
|
||||
// Data
|
||||
typename ::std::aligned_storage<
|
||||
sizeof(X)
|
||||
// , alignof(X) // Not here yet in all compilers
|
||||
>::type storage{};
|
||||
X* pp{ nullptr };
|
||||
};
|
||||
|
||||
// Restore definition of debug new
|
||||
#ifdef _DEBUG
|
||||
#ifdef _MSC_VER
|
||||
#undef THIS_FILE
|
||||
static char*THIS_FILE = __FILE__;
|
||||
#define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // __AUDACITY_MEMORY_X_H__
|
@ -94,8 +94,9 @@ for registering for changes.
|
||||
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "ShuttleGui.h"
|
||||
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/wxprec.h>
|
||||
#include <wx/listctrl.h>
|
||||
@ -104,7 +105,6 @@ for registering for changes.
|
||||
#include <wx/spinctrl.h>
|
||||
#include "Internat.h"
|
||||
#include "Experimental.h"
|
||||
#include "ShuttleGui.h"
|
||||
#include "Shuttle.h"
|
||||
#include "WrappedType.h"
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "Audacity.h"
|
||||
|
||||
#include "MemoryX.h"
|
||||
#include <wx/grid.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/string.h>
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "Tags.h"
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include <wx/wxprec.h>
|
||||
|
||||
@ -38,9 +41,6 @@
|
||||
#include <wx/window.h>
|
||||
#endif
|
||||
|
||||
#include "Tags.h"
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "FileDialog.h"
|
||||
#include "FileNames.h"
|
||||
#include "Internat.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "widgets/Grid.h"
|
||||
#include "xml/XMLTagHandler.h"
|
||||
|
||||
#include "MemoryX.h"
|
||||
#include <utility>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/hashmap.h>
|
||||
|
@ -11,7 +11,7 @@
|
||||
#ifndef __AUDACITY_TRACK_PANEL__
|
||||
#define __AUDACITY_TRACK_PANEL__
|
||||
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
#include <vector>
|
||||
|
||||
#include <wx/dcmemory.h>
|
||||
|
@ -48,7 +48,7 @@
|
||||
#ifndef __AUDACITY_UNDOMANAGER__
|
||||
#define __AUDACITY_UNDOMANAGER__
|
||||
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
#include "ondemand/ODTaskThread.h"
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "WaveClip.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <wx/log.h>
|
||||
|
@ -35,7 +35,7 @@ Track classes.
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include "MemoryX.h"
|
||||
|
||||
#include "float_cast.h"
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <wx/log.h>
|
||||
|
||||
#include "LegacyBlockFile.h"
|
||||
#include "../MemoryX.h"
|
||||
#include "../FileFormats.h"
|
||||
#include "../Internat.h"
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "PCMAliasBlockFile.h"
|
||||
#include "../FileFormats.h"
|
||||
#include "../Internat.h"
|
||||
#include "../MemoryX.h"
|
||||
|
||||
#include "../ondemand/ODManager.h"
|
||||
#include "../AudioIO.h"
|
||||
|
@ -70,6 +70,7 @@ to get its definition, rather than rolling our own.
|
||||
|
||||
#include "sndfile.h"
|
||||
#include "../Internat.h"
|
||||
#include "../MemoryX.h"
|
||||
|
||||
|
||||
static wxUint32 SwapUintEndianess(wxUint32 in)
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "../Experimental.h"
|
||||
|
||||
#include "MemoryX.h"
|
||||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
#include <wx/dynarray.h>
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "../LabelTrack.h"
|
||||
#include "../WaveTrack.h"
|
||||
#include "../MemoryX.h"
|
||||
|
||||
// Define keys, defaults, minimums, and maximums for the effect parameters
|
||||
//
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "TimeWarper.h"
|
||||
|
||||
#include <memory>
|
||||
#include "../MemoryX.h"
|
||||
|
||||
bool Generator::Process()
|
||||
{
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "Effect.h"
|
||||
|
||||
#include <memory>
|
||||
#include "../MemoryX.h"
|
||||
|
||||
#define NOISEREDUCTION_PLUGIN_SYMBOL XO("Noise Reduction")
|
||||
|
||||
|
@ -93,6 +93,7 @@
|
||||
#include "audacity/ConfigInterface.h"
|
||||
|
||||
#include "VSTEffect.h"
|
||||
#include "../../MemoryX.h"
|
||||
|
||||
// NOTE: To debug the subprocess, use wxLogDebug and, on Windows, Debugview
|
||||
// from TechNet (Sysinternals).
|
||||
|
@ -35,6 +35,10 @@ and ImportLOF.cpp.
|
||||
|
||||
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "Import.h"
|
||||
#include "ImportPlugin.h"
|
||||
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/string.h>
|
||||
@ -44,11 +48,8 @@ and ImportLOF.cpp.
|
||||
#include <wx/arrimpl.cpp>
|
||||
#include <wx/listimpl.cpp>
|
||||
#include "../ShuttleGui.h"
|
||||
#include "../Audacity.h"
|
||||
#include "../Project.h"
|
||||
|
||||
#include "Import.h"
|
||||
#include "ImportPlugin.h"
|
||||
#include "ImportPCM.h"
|
||||
#include "ImportMP3.h"
|
||||
#include "ImportOGG.h"
|
||||
|
@ -55,10 +55,12 @@ but little else.
|
||||
#ifndef __AUDACITY_IMPORTER__
|
||||
#define __AUDACITY_IMPORTER__
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include <wx/arrstr.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/list.h>
|
||||
#include "../MemoryX.h"
|
||||
|
||||
#include "../widgets/ProgressDialog.h"
|
||||
|
||||
|
@ -29,6 +29,7 @@ with changes in the SpectralSelectionBar.
|
||||
#include "../Audacity.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "../MemoryX.h"
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include <wx/wxprec.h>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef __AUDACITY_BUTTON__
|
||||
#define __AUDACITY_BUTTON__
|
||||
|
||||
#include <memory>
|
||||
#include "../MemoryX.h"
|
||||
#include <vector>
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "../Audacity.h"
|
||||
|
||||
#include "../MemoryX.h"
|
||||
#include <wx/defs.h>
|
||||
#include <wx/app.h>
|
||||
#include <wx/button.h>
|
||||
|
@ -21,9 +21,10 @@
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "XMLTagHandler.h"
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "../MemoryX.h"
|
||||
#include "../Internat.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -419,6 +419,7 @@
|
||||
<ClInclude Include="..\..\..\src\import\ImportGStreamer.h" />
|
||||
<ClInclude Include="..\..\..\src\import\MultiFormatReader.h" />
|
||||
<ClInclude Include="..\..\..\src\import\SpecPowerMeter.h" />
|
||||
<ClInclude Include="..\..\..\src\MemoryX.h" />
|
||||
<ClInclude Include="..\..\..\src\ModuleManager.h" />
|
||||
<ClInclude Include="..\..\..\src\NumberScale.h" />
|
||||
<ClInclude Include="..\..\..\src\prefs\GUISettings.h" />
|
||||
|
@ -1714,6 +1714,9 @@
|
||||
<ClInclude Include="..\..\..\src\TrackPanelListener.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\MemoryX.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\audacity.ico">
|
||||
|
Loading…
x
Reference in New Issue
Block a user