Sie sind auf Seite 1von 13

30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

Making Audio Plugins Part 3: Examining the


Code
PROGRAMMING,MAKINGAUDIOPLUGINS

Letshaveacloserlookattheexampleprojectfromlasttime.Themostimportantfilesare
resource.h,MyFirstPlugin.handMyFirstPlugin.cpp.Thepluginisasimplegainknobitchanges
thevolumeoftheaudiopassingthrough.

Constants, Flags and ImageResources


Openresource.hfromtheprojectnavigator.Thisfilehasconstantsforyourpluginsuchasname,
version,uniqueIDandimageresources.
Inlines2326youcansettheuniquePluginID:

// 4 chars, single quotes. At least one capital letter


#define PLUG_UNIQUE_ID 'Ipef'
// make sure this is not the same as BUNDLE_MFR
#define PLUG_MFR_ID 'Acme'

TheIDisimportantforcatalogingplugins.Youcanregisterithere.
Line56+definesanIDandimagepathfortheknobyouseewhenyouruntheApp:

// Unique IDs for each image resource.


#define KNOB_ID 101

// Image resource locations for this plug.


#define KNOB_FN "resources/img/knob.png"

Intheprojectnavigator,openResourcesimgknob.png.Itsaspritewith60differentknob
positionseachofthemis48x48Pixels.Sowhenyouruntheappandturntheknob,itdoesnt
rotatetheimage,butrathershowsacertain48x48Pixelportionofit.
Whynotjustrotateasingleimage?Imagineyouwantyourknobgraphictohaveaglossylookanda
dropshadow.Ifyouweretorotatethegraphic,theglossandshadowwouldalsoberotated,whichis
nothowitlooksintherealworld.

Furtherdowninresource.h,youcansetthesizeofyourpluginswindow:

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 1/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

#define GUI_WIDTH 300


#define GUI_HEIGHT 300

Trychangingthevaluesandruntheapp.

The Plugin ClassInterface


OpenMyFirstPlugin.h.Itjustcontainstheinterfaceforyourpluginclass.Thepublicpartcontains
Constructor,Destructorandthreememberfunctions:

Resetiscalledwhenthesamplerateischanged.

OnParamChangeiscalledwhenapluginparameterchanges,forexamplewhenyouturn
theknob.

ProcessDoubleReplacingisthecoreofyourplugin.Inthisfunctionyoucanprocess
incomingaudio.

Intheprivatesectiontheresjustadoubleholdingthecurrentgainvalue.

TheImplementation
Nowfortheinterestingpart!OpenMyFirstPlugin.cpp.Firstofallwecanseeanicetrickforenums:

enum EParams
{
kGain = 0,
kNumParams
};

Bysettingthefirstoptionto0andkNumParamsattheend,kNumParamsbecomesthenumberof
options(1inthiscase).
Thefollowingenumusestheconstantsdescribedinresource.handsetsthepositionoftheknobin
thepluginswindow:

enum ELayout
{
kWidth = GUI_WIDTH,
kHeight = GUI_HEIGHT,

kGainX = 100,
kGainY = 100,
kKnobFrames = 60
};

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 2/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

Italsodefinesthenumberofframesinknob.pngas60.
Belowthat,theconstructorimplementationstartsbysettingupthepluginsattributes:

//arguments are: name, defaultVal, minVal, maxVal, step, label


GetParam(kGain)->InitDouble("Gain", 50., 0., 100.0, 0.01, "%");

WecantseethevalueandpercentsignintheGUI,butthevaluecanbebetween0and100,the
defaultbeing50.Youmayhavenoticed,though,thattheknobisntattwelveoclock.Thisisbecause
oftheSetShape(2.)below.Setitto1.0andtheknobwillbeasyouexpect.SetShapegivesaknoba
nonlinearbehaviour.
Next,theconstructorcreatesagraphiccontextwiththerightsizeandcreatestheredbackground:

IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight);


pGraphics->AttachPanelBackground(&COLOR_RED);

Itthenloadstheknob.png,createsanewIKnobMultiControlwiththeimage,andattachesittothe
GUI.IKnobMultiControlistheC++classfortheGUIknob.NotehowkKnobFramesispassedto
indicatethatthespritecontains60frames.

IBitmap knob = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, kKnobFrames);


pGraphics->AttachControl(new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));

Finally,theconstructorattachesthegraphicscontext,anditcreatesadefaultpresetfortheplugin:

MakeDefaultPreset((char *) "-", kNumPrograms);

LetslookatOnParamChange(bottomofthefile).TheIMutexLockensuresThreadSafety,aconcept
wewilldiveintolater.Therestisjustaswitchtodotherightthingdependingonwhichparameter
waschanged:

case kGain:
mGain = GetParam(kGain)->Value() / 100.;
break;

Remember,thekGainparameterhasvaluesbetween0and100.Soafterdividingby100,weassign
theresult(between0and1)totheprivatemembermGain.

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 3/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

Sofar,wehavelookedathowaGUIiscreatedandhowitcanbelinkedtoparameterslikemGain.
Letsnowlookathowtheplugincanprocessincomingaudio.Inourcase,anaudiostreamisa
sequenceofdoublesamples,eachcontainingtheamplitudeatagivenpointintime.
ThefirstparametertoProcessDoubleReplacingisdouble** inputs.Asequenceofdoublevalues
canbepassedusingdouble*.Thepluginprocessestwo(stereo)orevenmorechannelsatonce,so
wehaveseveralsequencesofdoublesamples,thatis,double**.Thefirsttwolinesinthefunction
makeitmoreclear:

double* in1 = inputs[0];


double* in2 = inputs[1];

Now,in1pointstothefirstsequenceofsamples(leftchannel),in2tothesamplesfortheright
channel.Afterdoingthesamefortheoutputbuffer,wecaniterateovertheinputandoutputbuffers
toprocessthem:

for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2)


{
*out1 = *in1 * mGain;
*out2 = *in2 * mGain;
}

Foreverysample,wetaketheinputvalue,multiplyitbymGainandwriteittotheoutputbuffer.
nFramestellsushowmanysamplesthereareperchannelsoweknowhowlongthebuffersare.

Youmayhavenoticedthatwhenyouruntheapp,youcanhearyourselfthroughyourcomputer
speakers.Thisisbecausebydefault,thestandaloneapptakesyourcomputersmicrophoneasinput.
Tochangethis(andsomeotheraudiopreferences),gototheappspreferences:

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 4/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

SetabreakpointintheResetfunction.ChangetheSamplingRateontherightandclickApply.The
debuggerwillbreakinsideReset.Inthelowerrightwherelldbisrunning,enter
print GetSampleRate().

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 5/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

Noticehowyoucancallanyfunctionfromthedebuggeranditwillshowthecorrectreturnvalue.
PressStopintheupperleftcornerwhenyourereadytomoveon.
Nowitstimetoactuallycreatepluginversionsofourappandloadthemintoahost.Wellcover
thatinthenextpost!

FurtherReading
Tofillsomegaps,readtheseslidesbytheingeniusMr.OliLarkin.Theyexplainalotofthingsabout
WDLOL.

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 6/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

Ifyoufoundthisuseful,pleasefeelfreeto !

Megusta 36

17Comments MartinFinke'sBlog
1 Login

Recommend 1 Share SortbyOldest

Jointhediscussion

thackerthanthis3yearsago
Hello!yourtutorialseriesisincredible!I'vebeensearchingaroundforaninroadintomaking
AU'sforAGES!...IwonderifyoucanhelponsomethingprobablysosimpleWhenItry
changingtheManufactureID,orPLuginIDalthoughitrunsokAUlab,theplugindoesnot
validatewithinLogicorunderthevalidationscript.Igetanerror

ERROR:ViewComponentspecified,butcan'tbefound...
??I'evtriedlookingtoseeifandwhereimightneedtochangethenameofwhatI'mnow
specifying,butnoluck..

Best,
Nick
Reply Share

olilarkin>thackerthanthis3yearsago
hinick,

whenindoubtreduplicateoneoftheexampleprojectsandchangethingsonestepata
time.

itshouldbesufficientto:

supplyyourmanufacturernameasanargumenttotheduplicatescripte.g.
"./duplicate.pyIPlugEffect/MyNewPluginMyManufacturerName".Avoidspacesor
strangecharacters.

theneditthePLUG_UNIQUE_IDandPLUG_MFR_IDinresource.h

aslongasthoseIDSareuniquesandinthecorrectformatitshouldwork

ifyoutryandchangeanythingelse,e.g.bydirectlyeditingtheinfo.plistfilesyoumay
breakvalidation

hopethathelps

olilarkin
Reply Share

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 7/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

alfred3yearsago
whenitrytoaccessthepreferenceswindowmyapplicationgetsabortedbyafatalerrorsaying
thatvectoroutofbounds..

Firstchanceexceptionat0x7507c41finMyFirstPlugin.exe:MicrosoftC++exception:RtErrorat
memorylocation0x0016f378..
MyFirstPlugin.exehastriggeredabreakpoint
MicrosoftVisualStudioCRuntimeLibraryhasdetectedafatalerrorinMyFirstPlugin.exe.

thisiswhatsinthedebugwindow...
theerrorwhichcomesisvectorsubscriptoutofrange..canuhelpme?
Reply Share

MartinFinke Mod >alfred 3yearsago

Hello!Sorryfortheinconvenience!ThisseemstobethesameproblemreportedbyFabio
before.Pleaseseethiscomment:http://www.martinfinke.de/...
Reply Share

PerQA3yearsago
Hello!Icanonlyagreewitheveryoneelsehere.Thisisoneofthebesttutorialsever,allcategories!

However,Ihaverunintoaweirdproblem.Ican'tgetmyXcodeconsoletodisplayanydebug
output.Itseemsimpossibletochoosewhichthreadtowatch...The"busy"symbolinthedebug
navigatorontheleftneverstops.I'musingXcode5,butI'mnotveryexperiencedwithXcode.
ThereasonI'mpostingthequestionhereisthatIsuspecttheproblemisrelatedtothisproject,
sinceIhavebeenabletousetheconsoleinotherprojects.

Screenshot:
https://www.dropbox.com/s/a...
Reply Share

MartinFinke Mod >PerQA 3yearsago

Thankyouforthekindwords!:)

Ihaven'tusedXcode5,butitlookslikeyou'reonthewrongtab.Tryclickingthethreads
button,markedonthispicture:https://www.dropbox.com/s/u...

Hopethathelps,
Martin
Reply Share

PerQA>MartinFinke3yearsago
Yes,thishasbeenresolved.
Reply Share

PerQA3yearsago
Thistutorialisgreat!Everythinghasworkedsmoothly,butIcan'tgettheconsolecommandsto
http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 8/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog
Thistutorialisgreat!Everythinghasworkedsmoothly,butIcan'tgettheconsolecommandsto
work:

(lldb)printGetSampleRate()
error:useofundeclaredidentifier'GetSampleRate'
error:1errorsparsingexpression

Anyideaswhatcouldbecausingthis?
Reply Share

MartinFinke Mod >PerQA 3yearsago

Hello!Itsoundslike"GetSampleRate"isn'tvisibleinthatscope...areyousurethe
breakpointissetinsidethebodyofMyFirstPlugin::Reset?
Reply Share

PerQA>MartinFinke3yearsago
Yes,thebreakpointisthere.However,whenIruntheprogram,thereisnothing
displayedintheconsole.Theexecutiondoesnotstopatthebreakpointbyitself.If
Itype"printGetSampleRate()"intheconsolenothinghappens.IfImanually
pauseexecution,Igetthe(lldb)prompt,buttyping"printGetSampleRate()"
resultsinanerror:

(lldb)printGetSampleRate()
error:useofundeclaredidentifier'GetSampleRate'
error:1errorsparsingexpression

I'manXcodenewbie,soI'mprobablyjustdoingsomethingwronghere.
Reply Share

leedleleedlelee3yearsago
Hi!asothershavebeensaying,byfarthebesttutorialoutthere.Thankyouforthat.WhenItry
toruntheproject(Xcode5)buildfailsbecause"error:ThereisnoSDKwiththenameorpath
'/Users/tobalope/plugindev/wdlol/VST3_SDK/base/mac/macosx10.7'"anyIdeasonwhatit's
tryingtosay?I'monosxMavericksandalltheSDKswereinstalledproperly.
Reply Share

MartinFinke Mod >leedleleedlelee 3yearsago

Hello!Thanksforthefeedback!

That'sastrangeerror,becausethedirectory"wdlol/VST3_SDK/base/mac/macosx10.7"
isn'tsupposedtoexist.
Whenyougotoyourproject's"BuildSettings",whatoptionsareavailableforthe"Base
SDK"entryinthelist?
Reply Share

leedleleedlelee>MartinFinke3yearsago
thereare3,andosx10.7isn'tanyofthem...thoroughlyconfused:
OSX10.5$(BASE_SDK)
http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 9/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog
OSX10.5$(BASE_SDK)
OSX10.8
OSX10.9
andtheLatestoption(OSX10.9)
Reply Share

leedleleedlelee>MartinFinke3yearsago
Andthanksabunchforthereply,honestlywasn'texpectingone,asusuallyyou
don'tgetthem.Thankyouverymuch!
Reply Share

snacach3yearsago
Heydoesanyoneknowhowtodelaytheaudiobufferifiwanttoaddadelaytooneofthe
channels?Itsjustafewsamplesnothingbig,andtheamountisuserdefinedcontinouslybya
knob.Thanks
Reply Share

monkeyman32yearsago
Thisisbrilliant,thankssomuch,youarethebest
Reply Share

Andrew10monthsago
Howtochangepreferenceunderwindows?
Reply Share

Subscribe d AddDisqustoyoursiteAddDisqusAdd Privacy

Index
2015MartinFinkeImpressum

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 10/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 11/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 12/13
30/3/2017 MakingAudioPluginsPart3:ExaminingtheCodeMartinFinke'sBlog

http://www.martinfinke.de/blog/articles/audioplugins003examiningthecode/ 13/13

Das könnte Ihnen auch gefallen