[
  {
    "path": ".gitignore",
    "content": "source_code/.vs/**\r\nsource_code/Debug/*\r\n!source_code/Debug/audio_sniffer.dll\r\nsource_code/Release/*\r\n!source_code/Release/audio_sniffer.dll\r\nsource_code/x64/Debug/*\r\n!source_code/x64/Debug/audio_sniffer.dll\r\nsource_code/x64/Release/*\r\n!source_code/x64/Release/audio_sniffer-x64.dll\r\nsource_code/acam/Debug/*\r\nsource_code/acam/Release/*\r\nsource_code/acam/x64/Release/*\r\nsource_code/acam/x64/Debug/*\r\n\r\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"screen-capture-recorder-to-video-windows-free\"]\n\tpath = screen-capture-recorder-to-video-windows-free\n\turl = https://rdp@github.com/rdp/screen-capture-recorder-to-video-windows-free.git\n"
  },
  {
    "path": "ChangeLog.txt",
    "content": "0.4.6:\r\n  possible async fix LOL\r\n\r\n0.4.5:\r\n  possible async fix?\r\n  UI user friendly fixes\r\n  \r\n0.4.4:\r\n  UI fix for selecting devices\r\n\r\n0.4.3:\r\n  cleanup UI\r\n\r\n0.4.2:\r\n  updated to latest shortcuts\r\n  minor ui improvements\r\n\r\n0.4.1:\r\n  fix it to not use as much cpu win. 8 [untested]\r\n\r\n0.4.0\r\n  hopefully windows 8 friendlier...\r\n\r\n0.3.14\r\n  icons hopefully work after poor previous distro\r\n\r\n0.3.13\r\n\r\n  work with FMLE again <sigh>\r\n\r\n0.3.12\r\n?\r\n  \r\n0.3.11\r\n\r\nactually work with ffmpeg (scripts)\r\n\r\n0.3.10\r\n\r\nactually end ffmpeg's now\r\n\r\n0.3.9\r\n\r\nAccomodate for cmd.exe's redirect failures better (I hope).  I.e. let the program start.\r\n\r\nTry to write debug outputs to a consistent place now.\r\n\r\nAllow for spaces in dshow devices.\r\n\r\n0.3.8\r\n\r\n5.1 support now. If you have an ASUS Xonar card you may need to \"disable gx\" (the little gx green-light-button in the xonar control dock).\r\n\r\n0.3.7\r\n\r\nmake compatible with FMLE now [hopefully], minor cleanups, but FMLE still \"freezes\" a lot I'm not sure why.\r\n\r\n0.3.6\r\n\r\nhopefully fix ffmpeg complaining like:\r\n\r\n[libmp3lame @ 00670aa0] Que input is backward in time\r\nAudio timestamp 329016 < 329026 invalid, cliping00:05:29.05 bitrate= 738.6kbits/s\r\n[libmp3lame @ 00670aa0] Que input is backward in time\r\n\r\n\r\n0.3.5\r\n\r\nbug fixes in recording\r\n\r\n0.3.4\r\n\r\ncan also record to ac3/video now\r\nincludes the 64 bit device now, too.\r\n\r\n0.3.3 \r\n\r\ncleaner recorder, add broadcast links, allow xp users to install it, device didn't change at all\r\n\r\n0.3.2 \r\n\r\n fix for 64 bit windows, fix button recording\r\n\r\n0.3.1\r\n\r\nnew program icons, new record option\r\n\r\n0.3.0\r\n\r\nFix output for 48000 Hz etc. Sweet!\r\n\r\n0.2.10 \r\n\r\nFix installer.\r\n\r\n0.2.9 5/8/12\r\n\r\n  move an assertion, also we use a more \"directshowy\" fillbuffer now, which...is probably wrong but hey :P\r\n  more debug logs\r\n\r\n0.2.8 2-21-12\r\n  64 bit release kind of\r\n\r\n0.2.7 1-5-12\r\n  some minor directshow stuff has been updated, I believe\r\n\r\n0.2.6\r\n  some stuff from earlier, like adding bigger buffers and setting it to the graph's timestamp.\r\n\r\n0.2.3: better timestamps barely\r\n\r\n0.2.2: rename program files icon, new README\r\n\r\n0.2.1: slightly better gui\r\n\r\n0.2.0: make the capture thread realtime priority (better performance), add some record scripts, make timestamps match up now [I think this is right]"
  },
  {
    "path": "LICENSE",
    "content": "Contact me about a (free) open source license (MIT ?).\n\nBasically I can release the code under \"some license\", but it cannot be the GPL, or so I'm told:\nhttp://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/a3e8f60b-39e4-4621-837b-50a9a9a469b7\n\nIn essence, since its its own DLL (and I hereby grant license to distribute it free of charge, no warranty given of course) you can use it \"verbatim\" in your project, so you don't need to worry too much about its license per se, since it's \"its own dll\" project.\n\nCheers!\n"
  },
  {
    "path": "README.TXT",
    "content": "﻿This is an audio capture device allowing you to capture all the \"wave out sound\" that is playing on your speakers \r\n(i.e. record what you hear) for Windows 7/Vista.  Windows XP users please read the \"history\" section\r\nfor something else you can try in its place.\r\n\r\nNB THAT IF YOU WANT TO USE WITH SCREEN RECORDING THEN PLEASE INSTALL\r\nTHE MORE FULL FEATURED \r\nhttps://github.com/rdp/screen-capture-recorder-to-video-windows-free\r\n\r\n== Installation ==\r\n\r\nTo use, download+install from here: \r\n\r\nhttp://sourceforge.net/projects/screencapturer/files\r\n\r\n(it says \"on screen capture recorder\"\r\nthen use it via its included start menu utilities \"start menu/windows orb -> screen capturer -> ...\", or use it\r\nas input to any other program that can take directshow devices as an input.\r\n\r\n== Usage ==\r\n\r\nExample: VLC media player: media [menu] -> open capture device -> select capture audio device \"virtual-audio-capturer\"\r\n\r\nExample: ffmpeg (to save audio to file yo.mp3 from what is currently playing):\r\n$ ffmpeg  -f dshow -i audio=\"virtual-audio-capturer\" yo.mp3\r\n\r\n(also see https://github.com/rdp/screen-capture-recorder-program if you want to stream your desktop with audio\r\nas well or capture it or the like)\r\n\r\nNB that you'll need java JRE previously installed to use the included helper apps.\r\n\r\n== Troubleshooting/Contact/feature requests ==\r\n\r\nBasically, if you have a problem/feature request (ex: recording multiple audio at the same time, adding ability to strip silence, etc.), ask!\r\n\r\nrogerdpack@gmail.com or mailing list http://groups.google.com/group/roger-projects\r\nOr submit an idea/feature request to our uservoice: http://rdp.uservoice.com\r\n\r\nAlso note that VLC directshow input might need buffers of at least 40 or 50 ms or it fails for some reason.  But trying even higher might help.\r\n\r\nNotes from users:\r\n\r\n\"I was able to reduce the VLC delay messages by changing the output frame rate from 30 to 24 and increasing the dshow buffer from 200 to 20000\" (you shouldn't need to though).\r\n\r\nIf I make the \"PlayOn Virtual Audio Device\" or the \"Virtual Audio Cable\" the Playback Default device instead of the Realtek speakers all the problems with your filter go away. So it would seem the problem is really with the Realtek Driver. \r\n\r\nIf it doesn't work well for you (of course please report this fact), then you may be able to turn on \"record what you hear\"/\"wave out mix\" for your system,\r\nsee \"alternatives\".\r\n\r\nIf that also doesn't work then you could use a small audio cable to connect your input jack with your output jack,\r\nand then record using that.  See end section of \"alternatives\".\r\n\r\n\r\nIf you use it in VLC you'll need a directshow cache of at least 40ms, for whatever reason.\r\nAlso note that it's tuned set to work best for recording \"what you hear\" \r\nif this doesn't work for you then ping me I maybe could add a more \"realtime\" option or \r\nsomething.\r\nBasically any feedback welcome, if it doesn't work.\r\nAlso note that if you turn down your system volume within windows, it will still continue recording\r\nor playing, as apparently it captures it at \"normal volume\" regardless of how high your speaker output is.\r\nAny feedback welcome, including feature requests like \"support more audio channels than 2\".\r\n\r\nIf you want a smaller download you can just download the file source_code\\Release\\audio_sniffer.ax then run regsvr32 audio_sniffer.ax on it as an admin user, or use the \"just device\" distro.\r\n\r\n\r\n= History/XP users/Alternatives =\r\n\r\nBasically, with windows XP, you can typically already \"record what you hear\"\r\nRun sndvol32 (Start menu -> Accessories -> Volume/Audio), choose options [menu] -> properties -> recording radio button, click ok, \r\nnow click the \"select\" checkbox underneath \"Wave Out Mix\"\r\n\r\nNow with for example VLC choose \"Open Capture Device\" -> Audio Device Name -> select \"your soundcard's name\" (other\r\nprograms just select your soundcard's name).\r\n\r\nWith Windows Vista/7, for some reason many sound card drivers do not include this as an option.\r\nSome do though. You can check if yours already does by following instructions here:\r\nhttp://downloadsquad.switched.com/2007/01/15/how-to-enable-wave-out-recording-in-vista\r\nYou may want to download and install new audio drivers first before looking for it, sometimes that helps.\r\n\r\nIf you're in Vista/Windows 7 and see a \"Wave Out Mix\" following the above instructions\r\nthen you're good to go: enable it, and you can use it (you thus don't need virtual-audio-capture-grabber-device at\r\nall).\r\n\r\nIf you don't see it then you're in luck this, device is for you.\r\nWindows Vista/7 offer a new interface called a \"loopback\" adapter that captures the outgoing audio just\r\nas it is sent to your speakers [1].\r\n\r\nThis little utility captures the loopback audio and offers it to you as an input device\r\nthat you can then record (it's captured as a directshow audio capture device, if that means anything to you).\r\nVLC can use this to record, for example.  There are some example apps included with this package.\r\n\r\nBasically I programmed this as an open source (free) competitor to virtual audio cable.\r\nPing me if you want me to convert it into a \"real\" kernel level audio device so that any program can use it,\r\nnot just directshow compatible ones.\r\nPing me if you want an easier \"start/stop\" recorder, too.\r\n\r\nAnother option is \"If your sound card doesn't have the option to record what you hear, \r\nuse a cable (with 3.5mm headphone jacks on both ends) to connect the line out of your \r\nsound card to the line in (using a splitter if you need to be able to hear what you're doing, \r\nand disabling mic boost if you use a microphone input).\"\r\n\r\nBut that's hardware and this is a software answer :)\r\n\r\n== related ==\r\n\r\nThere are a handful of (mostly closed source) similar projects, some with more functionality <heh>\r\nsee http://superuser.com/questions/98720/is-there-a-free-or-open-source-equivalent-to-vac\r\n\r\n== building ==\r\n\r\nIf you want to hack on the source code see the file how_to_setup_code.txt\r\n\r\n== Attribution ==\r\n\r\nSome source code originally from the windows SDK samples, some based on [1]\r\nSo you'll probably need to install the Windows SDK before playing around with the source code, legally.\r\n\r\nEnjoy!\r\n\r\n[1] http://blogs.msdn.com/b/matthew_van_eerde/archive/2008/12/16/sample-wasapi-loopback-capture-record-what-you-hear.aspx\r\n"
  },
  {
    "path": "TODO",
    "content": "== actually do==\r\n  a \"real\" kernel level receive from driver\r\n    esp. if I ever need buffering in dshow, intead...\r\n\r\n\tit does not record wav right?!\r\n\t\r\n\t\r\nif no audio device, return -1 or what not...\r\n\r\n== maybe ==\r\n\r\n  simpler/easier \"just audio straight\" GUI recorder...\r\n\r\n== meh/never ==\r\n\r\nit can be set to 24 bit audio if their input \"is\" 24 bit audio? maybe?\r\n\r\nit doesn't complain whn I choose an unwritable dir and writing fails?  It also displays as \"recording to /\\\" if I choose the base?  \r\n\r\nbad icons? background console?\r\n\r\nthis gui setup is awkward...\r\n\r\nnew name?\r\n  new web page/real web page\r\n\r\nprovide a \"straight -> 2\" pin always, for those 5.1'ers\r\n  provide a \"32 bit\" pin\r\n\r\nVAC: use real mutex no sleep(1)\r\n\r\n2 pins, one with 32 bit audio :)\r\n\r\nsome thing that shows the current \"bars\" of how much it could/would be capturing...\r\n\r\nfigure out/debug pauses in FME when clicking \"stop\"...huh?\r\n\r\nfaster script startup speeds?\r\n\r\nOne feature I had thought of would be a \"strip trailing silence\" option or the like.  I know if I were recording things I might like it :)\r\nAnother option that might be useful/interesting might be to record/merge several audio input streams at a time.  This might be useful for recording skype calls so you can get the microphone as well as the \"audio out\".\r\n\r\n  copy broadcaster here I guess?\r\n\r\n  fix \"everybody's bug\"\r\n      sleep 0's?\r\n      reproduce?\r\n      timestamps offset with a maximum end time?\r\n     max(should, real) etc.!\r\n      maybe it's fixed/ok? http://msdn.microsoft.com/en-us/library/windows/desktop/dd407208(v=vs.85).aspx\r\n\r\n\t  maybe something like VAC's usefulness for gamers or something? \r\n\r\ntry \"mixing\" of several? http://msdn.microsoft.com/en-us/library/windows/hardware/ff537517%28v=vs.85%29.aspx\r\n  \r\nsystem tray \"start\" \"stop\"\r\n\r\nfigure out a way to stream to say ps3: http://superuser.com/questions/44629/application-to-stream-any-audio-to-upnp-device-xbox-360\r\n  have an \"easy streamer\" option\r\n    or just have screen capture so it can stream, too :P\r\n    \r\nhave a \"real\" webpage for it so I can track analytics/adsense\r\n\r\ndo the propaganda file\r\n  also propaganda something like \"record what you hear program\" or whatever to compete with freecorder and the like\r\n\r\ncan \"convert\" any audio file to an media player friendlier mp3 :)\r\n\r\nhigher quality, like more than 2 tracks/44Khz [possible?]\r\n\r\nwork when paused (esp. VLC)...hmm...do we need a realtime option? single-threaded m/b?\r\n  actually...in this instance shouldn't I be calculating my own timestamps, starting from when I first got non discontinuous data? hmm...\r\n   pass in the current ref time...hmm...or maybe if the buffer is too large I arbitrarily dump some of it?  I don't accomodate VLC pause but \r\n   maybe I'm ok realtime still, as is currently?  \r\n  \r\nreal ddk thing [if anybody asks for it]\r\n\r\n== notes ==\r\n\r\nnote: the silence thing I think works...based on not hitting that line...\r\nnote: output setting volume \"doesn't\" matter...\r\n"
  },
  {
    "path": "downloads_have_moved_here.txt",
    "content": "please download releases from here (it is packaged within it):\r\n\r\nhttps://github.com/rdp/screen-capture-recorder-to-video-windows-free"
  },
  {
    "path": "how_to_setup_code.txt",
    "content": "Install Windows 10 SDK and at least Visual Studio Express 2019\r\n\r\nThe directshow baseclasses example is no longer part of the Windows SDK. Get\r\nthe samples by cloning https://github.com/microsoft/Windows-classic-samples \r\nto D:\\build\r\n\r\nmkdir D:\\build\r\ncd /d D:\\build\r\ngit clone https://github.com/microsoft/Windows-classic-samples\r\n\r\nBuild directshow baseclasses from the SDK: \r\nOpen \r\nD:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses\\baseclasses.sln\r\nin Visual Studio, let Visual Studio upgrade the version and build\r\nit (all combinations Debug x86, Release x86, x64... especialy for the platform you want to build \r\naudio_sniffer.dll for).\r\n\r\nClone the virtual-audio-capture-grabber-device repository\r\n\r\ncd /d D:\\build\r\ngit clone https://github.com/rdp/virtual-audio-capture-grabber-device\r\ncd virtual-audio-capture-grabber-device\r\ngit submodule update --init --recursive\r\n\r\nthen open the visual studio project file \\source_code\\acam\\acam.vcxproj \r\n\r\nlet Visual Studio upgrade the version and build it.\r\n\r\nIt outputs a .dll file that you \"register\" via (in administrator console) \r\n$ regsvr32 XXX.dll (and unregister when you're done with regsvr32 /u XXX.dll)\r\n\r\nIn essence this is the \"WASAPI loopback\" sample\r\nhttps://blogs.msdn.microsoft.com/matthew_van_eerde/2008/12/16/sample-wasapi-loopback-capture-record-what-you-hear/\r\n\r\ncombined with the \"capture source filter\" http://tmhare.mvps.org/downloads.htm but with many improvements :)\r\n\r\nSo go to those two to learn the basics.\r\n\r\nThis is meant to provide a \"directshow filter\" you can use in your graph, not a demo of how to do graphs.\r\n"
  },
  {
    "path": "innosetup_installer_options.iss",
    "content": "; use the innosetup from screen-capturer instead now instead of this one...even though \"it's\" the submodule, that's how its paths are setup as of today..."
  },
  {
    "path": "notes",
    "content": "notes:\r\n\r\n= 5.1 =\r\n\r\nwith \"gx\" enabled, I could still capture 5.1 when playing a file through WMP (and it could play in 5.1).\r\nwith \"gx\" disabled, SDL_Audio couldn't create a 5.1 output\r\nwith \"right click and test\" from control panel, with or without gx enabled, could capture.\r\nMaybe it's an openSDL bug? :)\r\nshould still report it to ASUS though...in 5.1 with GX enabled, it does not capture wave's played by ffplay (even stereo).\r\n \r\n= the need for \"true\" =\r\n \r\n\"C:\\Programs\\VLC TEST 1.1.10\\vlc.exe\" -vvv dshow:// --sout=#transcode{venc=ffmpeg,vcodec=mp2v,vb=10000,fps=30,scale=0.5,width=1280,acodec=mp3,ab=192,channels=2,samplerate=44100,soverlay}:std{access=http,mux=ts,dst=:8081} --no-sout-rtp-sap --no-sout-standard-sap --ttl=1 --sout-keep  :dshow-vdev=screen-capture-recorder :dshow-adev=virtual-audio-capturer  :dshow-caching=0\r\n  I think play it with VLC, or with mplayer, and/or substitute VAC with it, see what happens.\r\n   check for \"tearing\" and out of sync audio...\r\n  \r\n = random =\r\n \r\n increase dshow-caching=200 to dshow-caching=900 ?\r\n \r\n \r\nng VLC 1.0.0 native, w\r\n\r\ndisable \"cool'n'quiet\"\r\n  Changing back to High Performance Power Plan is a workaround to fix it, but consumes a lot more energy and produces more heat.\r\n\r\n\r\n\r\nsubtracting at beginning didn't help it...\r\n\r\nadding \"sleeps\"\r\nresulted in this message very fast:\r\n...\r\nmain debug: Decoder buffering done in 0 ms\r\nmain warning: received buffer in the future\r\nmain warning: received buffer in the future\r\nmain warning: PTS is out of range (-10000), dropping buffer\r\nmain warning: PTS is out of range (-21000), dropping buffer\r\nmain warning: PTS is out of range (-32000), dropping buffer\r\nmain warning: output date isn't PTS date, requesting resampling (68000)\r\n*repeat* with similar numbers.\r\n\r\n\"normal\" doesn't have the output date isn't PTS date message, just\r\n  main warning: buffer is 40569 late, triggering upsampling\r\n  main warning: resampling stopped after 5324000 usec (drift: -1875)\r\n  after awhile\r\n\r\nMIN() didn't help VLC\r\n\r\nwith \"choose the MAX I know what you want!:\"\r\ncreeps up,\r\ntons of\r\n\r\nmain warning: received buffer in the future\r\nmain warning: PTS is out of range (-10000), dropping buffer\r\nmain warning: PTS is out of range (-33219), dropping buffer\r\nmain warning: buffer is 68850 late, triggering upsampling\r\nmain warning: output date isn't PTS date, requesting resampling (58561)\r\nmain warning: audio drift is too big (120953), dropping buffer\r\nmain warning: timing screwed, stopping resampling\r\nmain warning: buffer is 110795 late, triggering upsampling\r\nmain warning: audio drift is too big (120316), dropping buffer\r\nmain warning: output date isn't PTS date, requesting resampling (45000)\r\nmain warning: audio drift is too big (155214), dropping buffer\r\n\r\n\r\nwith \"subtract\":\r\n\r\nmain debug: Buffering 80%\r\nmain debug: Buffering 90%\r\nmain debug: Stream buffering done (100 ms in 110 ms)\r\nmain debug: Decoder buffering done in 0 ms\r\nmain warning: received buffer in the future\r\nmain warning: PTS is out of range (-10000), dropping buffer\r\nmain warning: PTS is out of range (-33219), dropping buffer\r\nmain warning: PTS is out of range (-9841), dropping buffer\r\nmain warning: PTS is out of range (-18841), dropping buffer\r\nmain warning: output date isn't PTS date, requesting resampling (40159)\r\nmain warning: buffer is 68108 late, triggering upsampling\r\nmain warning: output date isn't PTS date, requesting resampling (45000)\r\nmain warning: resampling stopped after 7688000 usec (drift: -40807)\r\nmain warning: buffer is 40966 late, triggering upsampling\r\nmain warning: output date isn't PTS date, requesting resampling (45000)\r\nmain warning: resampling stopped after 5839000 usec (drift: -43702)\r\nmain warning: buffer is 43860 late, triggering upsampling\r\nweird weird stuff there...gah!\r\n\r\n\r\nnormal \"set it like they tell me to:\"\r\n\r\nmain debug: Buffering 71%\r\nmain debug: Buffering 81%\r\nmain debug: Buffering 91%\r\nmain debug: Stream buffering done (101 ms in 95 ms)\r\nmain debug: Decoder buffering done in 0 ms\r\nmain warning: PTS is out of range (-10000), dropping buffer\r\nmain warning: PTS is out of range (-20158), dropping buffer\r\nmain warning: PTS is out of range (-30317), dropping buffer\r\n\r\nafter a long while:\r\n\r\nmain warning: buffer is 40176 late, triggering upsampling\r\nmain warning: output date isn't PTS date, requesting resampling (44524)\r\nmain warning: resampling stopped after 5862000 usec (drift: -42776)\r\nmain warning: buffer is 42777 late, triggering upsampling\r\nmain warning: resampling stopped after 6079000 usec (drift: 765)\r\nmain warning: output date isn't PTS date, requesting resampling (45000)\r\nmain warning: buffer is 44792 late, triggering upsampling\r\nmain warning: resampling stopped after 6225000 usec (drift: 1394)\r\n\r\n\r\n\r\n\r\nthreaded:\r\n\r\nwith 5 other threads, dual core, they both seem to start giving bad feedback, possibly single threaded with smaller sizes [?]\r\n\r\nwith high prioritied single thread:  4480, some big though...seems as good as single thread maybe...\r\n\r\nseemed that it avoided discontinuity messages even if \"lots\" of them were running at once [!]\r\n  unless one had to pause to delete a file, then it could get it.\r\n\r\n\r\nvirtual \"they can play into me:\"\r\n  http://social.msdn.microsoft.com/Forums/en-AU/wdk/thread/5dce267b-d452-4d1c-ad18-0c5b6edcff5f"
  },
  {
    "path": "propaganda",
    "content": "waveout mix 1600\r\naudio sniffer 390\r\nrecord what you hear 12,000\r\nvirtual audio interface 320\r\naudio loopback 1900\r\nrecord speakers 12,100\r\n\r\naudio capture 246_000\r\nvirtual audio 135_000\r\naudio grabber 165,000\r\n\r\nvirtual audio capture grabber device\r\n\r\nalternative.to virtual audio cable\r\n\r\npropaganda from the propaganda fella\r\n\r\nhttp://superuser.com/questions/190093/how-to-play-mp3-files-into-the-microphone-input\r\nhttp://www.google.com/search?rlz=1C1SKPL_enUS426US426&sourceid=chrome&ie=UTF-8&q=record+what+you+hear+windows+7&safe=active"
  },
  {
    "path": "source_code/acam/Dll.cpp",
    "content": ""
  },
  {
    "path": "source_code/acam/ReadMe.txt",
    "content": "TODO:\r\n\r\nmsvad: yeah do it some day LOL\r\n\r\nnotes:\r\nbig buffer: blips 2, 3\r\na little \"fast forward snip\" at the beginning when it's catching up (and has tons of blips)...\r\n\r\nwith threads 1, full size:\r\n  a few fast forwards...\r\n\r\n\r\nwith threads 2:\r\nlots of fast forward blips at the beginning, blips through, \"stumbles forward\"\r\n\r\nwith threads 2, actually using it, still just 2 blips\r\nI think it's ok to use."
  },
  {
    "path": "source_code/acam/acam.def",
    "content": "EXPORTS\r\n    DllGetClassObject PRIVATE\r\n    DllCanUnloadNow PRIVATE\r\n    DllRegisterServer PRIVATE\r\n    DllUnregisterServer PRIVATE"
  },
  {
    "path": "source_code/acam/acam.h",
    "content": "// The following ifdef block is the standard way of creating macros which make exporting \r\n// from a DLL simpler. All files within this DLL are compiled with the ACAM_EXPORTS\r\n// symbol defined on the command line. This symbol should not be defined on any project\r\n// that uses this DLL. This way any other project whose source files include this file see \r\n// ACAM_API functions as being imported from a DLL, whereas this DLL sees symbols\r\n// defined with this macro as being exported.\r\n#ifdef ACAM_EXPORTS\r\n#define ACAM_API __declspec(dllexport)\r\n#else\r\n#define ACAM_API __declspec(dllimport)\r\n#endif\r\n\r\n#include <streams.h>\r\n#include <dllsetup.h>\r\n#include <stdio.h>\r\n#include <Windows.h>\r\n#include \"common.h\"\r\n#include <assert.h>\r\n\r\n//extern CCritSec m_cSharedState; // unused\r\n\r\n// This class is exported from the acam.dll\r\nclass ACAM_API Cacam {\r\npublic:\r\n\tCacam(void);\r\n\t// TODO: add your methods here.\r\n};\r\n\r\nextern ACAM_API int nacam;\r\n\r\nACAM_API int fnacam(void);\r\n\r\nEXTERN_C const GUID CLSID_VirtualCam; // reuse it...\r\n\r\n// the \"parent\" class\r\nclass CVCam : public CSource // not needed \"public IMediaFilter\" since CSource is already that\r\n{\r\npublic:\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IUnknown\r\n    //////////////////////////////////////////////////////////////////////////\r\n    static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);\r\n    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r\n\r\n    IFilterGraph *GetGraph() {return m_pGraph;};\r\n\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IMediaFilter overrides [added]\r\n    //////////////////////////////////////////////////////////////////////////\r\n    STDMETHODIMP Run(REFERENCE_TIME tStart); // it does call this...\r\n    STDMETHODIMP GetState(DWORD dw, FILTER_STATE *pState);\r\n    STDMETHODIMP Pause();\r\n\r\n\t//protected:\r\n\r\n   // IReferenceClock *m_pClock; // wrong place I think\r\n\r\n\t// CBaseFilter\r\n\tSTDMETHODIMP Stop();\r\n\r\nprivate:\r\n    CVCam(LPUNKNOWN lpunk, HRESULT *phr);\r\n};\r\n\r\n// child\r\n// I think stream means \"a pin\" as it were...\r\nclass CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsPropertySet, public IAMBufferNegotiation, public IAMFilterMiscFlags //IAMPushSource\r\n{\r\npublic:\r\n\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IUnknown\r\n    //////////////////////////////////////////////////////////////////////////\r\n    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r\n    STDMETHODIMP_(ULONG) AddRef() { return GetOwner()->AddRef(); }                                                          \\\r\n    STDMETHODIMP_(ULONG) Release() { return GetOwner()->Release(); }\r\n\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IQualityControl\r\n    //////////////////////////////////////////////////////////////////////////\r\n    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);\r\n\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IAMStreamConfig\r\n    //////////////////////////////////////////////////////////////////////////\r\n    HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt);\r\n    HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt);\r\n    HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize);\r\n    HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC);\r\n\r\n\t// IAMPushSource [not implemented yet]\r\n\t/*HRESULT STDMETHODCALLTYPE GetLatency(REFERENCE_TIME *in) {return S_OK;};\r\n\tHRESULT STDMETHODCALLTYPE GetPushSourceFlags(ULONG *in){return S_OK;};\r\n\tHRESULT STDMETHODCALLTYPE SetPushSourceFlags(ULONG) {return S_OK;};\r\n\tHRESULT STDMETHODCALLTYPE SetStreamOffset(REFERENCE_TIME) { return E_FAIL; }\r\n\tHRESULT STDMETHODCALLTYPE GetStreamOffset(REFERENCE_TIME *) {return S_OK;};\r\n\tHRESULT STDMETHODCALLTYPE GetMaxStreamOffset(REFERENCE_TIME *) {return S_OK;};\r\n\tHRESULT STDMETHODCALLTYPE SetMaxStreamOffset(REFERENCE_TIME) {return S_OK;};*/\r\n\r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  IKsPropertySet\r\n    //////////////////////////////////////////////////////////////////////////\r\n    HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, DWORD cbInstanceData, void *pPropData, DWORD cbPropData);\r\n    HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, void *pInstanceData,DWORD cbInstanceData, void *pPropData, DWORD cbPropData, DWORD *pcbReturned);\r\n    HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);\r\n    \r\n    //////////////////////////////////////////////////////////////////////////\r\n    //  CSourceStream\r\n    //////////////////////////////////////////////////////////////////////////\r\n    HRESULT FillBuffer(IMediaSample *pms);\r\n    HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc, ALLOCATOR_PROPERTIES *pProperties);\r\n    HRESULT CheckMediaType(const CMediaType *pMediaType);\r\n    HRESULT GetMediaType(int iPosition, CMediaType *pmt);\r\n    HRESULT SetMediaType(const CMediaType *pmt);\r\n    HRESULT OnThreadCreate(void);\r\n    HRESULT OnThreadDestroy(void);\r\n\t/* don't seem to get called... */\r\n    HRESULT Stop(void);\r\n    HRESULT Exit(void);\r\n    HRESULT Inactive(void); // ondisconnect :)\r\n\r\n    CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName);\r\n    ~CVCamStream();\r\n    CRefTime     m_rtPreviousSampleEndTime;\r\n\r\n\r\n\t// IAMBufferNegotiation -- never gets called...\r\n\tHRESULT STDMETHODCALLTYPE SuggestAllocatorProperties( /* [in] */ const ALLOCATOR_PROPERTIES *pprop);\r\n    HRESULT STDMETHODCALLTYPE GetAllocatorProperties( ALLOCATOR_PROPERTIES *pprop);\r\n\r\n\t// IAMFilterMiscFlags -- never gets called...\r\n\tULONG STDMETHODCALLTYPE GetMiscFlags() { return AM_FILTER_MISC_FLAGS_IS_SOURCE; }\r\n\r\nprivate:\r\n    CVCam *m_pParent;\r\n    // unused now? REFERENCE_TIME m_rtLastTime;\r\n    HBITMAP m_hLogoBmp;\r\n    // IReferenceClock *m_pClock; // did we ever used to set this up?\r\n\r\n\tHRESULT setAsNormal(CMediaType *pmt);\r\n\r\n};\r\n"
  },
  {
    "path": "source_code/acam/acam.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{B6830EAD-C98E-490D-8999-CAA246788BF7}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>acam</RootNamespace>\r\n    <ProjectName>audio_sniffer</ProjectName>\r\n    <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <LibraryPath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses\\Debug;$(WindowsSDK_LibraryPath_x86);$(LibraryPath);$(UniversalCRT_LibraryPath_x86)</LibraryPath>\r\n    <IncludePath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses;$(IncludePath);$(WindowsSDK_IncludePath);$(UniversalCRT_IncludePath);$(VC_IncludePath)</IncludePath>\r\n    <TargetExt>.dll</TargetExt>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <LibraryPath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses\\x64\\Debug;$(WindowsSDK_LibraryPath_x64);$(LibraryPath);$(UniversalCRT_LibraryPath_x64)</LibraryPath>\r\n    <IncludePath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses;$(WindowsSDK_IncludePath);$(IncludePath);$(UniversalCRT_IncludePath);$(VC_IncludePath)</IncludePath>\r\n    <TargetExt>.dll</TargetExt>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <IncludePath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses;$(IncludePath);$(WindowsSDK_IncludePath);$(UniversalCRT_IncludePath);$(VC_IncludePath)</IncludePath>\r\n    <LibraryPath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses\\Release;$(WindowsSDK_LibraryPath_x86);$(LibraryPath);$(UniversalCRT_LibraryPath_x86)</LibraryPath>\r\n    <TargetExt>.dll</TargetExt>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <IncludePath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses;$(IncludePath);$(WindowsSDK_IncludePath);$(UniversalCRT_IncludePath);$(VC_IncludePath)</IncludePath>\r\n    <LibraryPath>D:\\Build\\Windows-classic-samples\\Samples\\Win7Samples\\multimedia\\directshow\\baseclasses\\x64\\Release;$(WindowsSDK_LibraryPath_x64);$(LibraryPath);$(UniversalCRT_LibraryPath_x64)</LibraryPath>\r\n    <TargetExt>.dll</TargetExt>\r\n    <TargetName>audio_sniffer-x64</TargetName>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ACAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Windows</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <AdditionalDependencies>strmbasd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Avrt.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <ModuleDefinitionFile>acam.def</ModuleDefinitionFile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ACAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Windows</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <AdditionalDependencies>strmbasd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Avrt.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <ModuleDefinitionFile>acam.def</ModuleDefinitionFile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ACAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Windows</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <AdditionalDependencies>strmbase.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Avrt.lib;%(AdditionalDependencies);</AdditionalDependencies>\r\n      <ModuleDefinitionFile>acam.def</ModuleDefinitionFile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ACAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Windows</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <AdditionalDependencies>strmbase.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Avrt.lib;%(AdditionalDependencies);</AdditionalDependencies>\r\n      <ModuleDefinitionFile>acam.def</ModuleDefinitionFile>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <None Include=\"ReadMe.txt\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"acam.h\" />\r\n    <ClInclude Include=\"common.h\" />\r\n    <ClInclude Include=\"silence.h\" />\r\n    <ClInclude Include=\"stdafx.h\" />\r\n    <ClInclude Include=\"targetver.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"directshow_fillbuffer.cpp\" />\r\n    <ClCompile Include=\"directshow_stuff.cpp\" />\r\n    <ClCompile Include=\"loopback-capture-helpers.cpp\" />\r\n    <ClCompile Include=\"loopback-capture.cpp\" />\r\n    <ClCompile Include=\"dll_main.cpp\">\r\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</CompileAsManaged>\r\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</CompileAsManaged>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n      </PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n      </PrecompiledHeader>\r\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</CompileAsManaged>\r\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</CompileAsManaged>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n      </PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n      </PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"silence_background_thread.cpp\" />\r\n    <ClCompile Include=\"silence_control.cpp\" />\r\n    <ClCompile Include=\"stdafx.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"utilities.cpp\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "source_code/acam/acam.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"ReadMe.txt\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"stdafx.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"targetver.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"acam.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"common.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"silence.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"stdafx.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"loopback-capture.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"loopback-capture-helpers.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"directshow_stuff.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"directshow_fillbuffer.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"dll_main.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"utilities.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"silence_control.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"silence_background_thread.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "source_code/acam/acam.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LocalDebuggerCommand>C:\\installs\\graphstudionext.exe</LocalDebuggerCommand>\r\n    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r\n    <LocalDebuggerCommandArguments>c:\\dev\\ffmpeg\\audio\\audio_only.grf</LocalDebuggerCommandArguments>\r\n    <LocalDebuggerWorkingDirectory>c:\\dev\\ffmpeg\\audio</LocalDebuggerWorkingDirectory>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LocalDebuggerCommand>C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe</LocalDebuggerCommand>\r\n    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LocalDebuggerCommand>c:\\vids\\ffmpeg.exe</LocalDebuggerCommand>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LocalDebuggerCommandArguments>-f dshow -r 4 -i video=screen-capture-recorder:audio=virtual-audio-capturer -y yo.mp4</LocalDebuggerCommandArguments>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LocalDebuggerWorkingDirectory>c:\\vids</LocalDebuggerWorkingDirectory>\r\n    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LocalDebuggerCommand>C:\\installs\\ffmpeg-20160415-git-21acc4d-win64-static\\bin\\ffmpeg.exe</LocalDebuggerCommand>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LocalDebuggerCommandArguments>-f dshow -i audio=virtual-audio-capturer -y out.mp3</LocalDebuggerCommandArguments>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LocalDebuggerWorkingDirectory>c:\\dev</LocalDebuggerWorkingDirectory>\r\n    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "source_code/acam/common.h",
    "content": "#include <mmdeviceapi.h>\r\n#include <mmsystem.h>\r\n#define SECOND_FRACTIONS_TO_GRAB 16\r\n\r\n// dangerous macros!\r\n#define MIN(a, b) (((a) < (b)) ? (a) : (b)) \r\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\r\nextern bool bDiscontinuityDetected;\r\nextern bool bVeryFirstPacket;\r\nvoid ShowOutput(const char *str, ...);\r\nHRESULT set_config_string_setting(LPCTSTR szValueName, wchar_t *szToThis );\r\n\r\nint getHtzRate(HRESULT *hr);\r\nint getBitsPerSample();\r\nint getChannels();\r\n\r\nHRESULT LoopbackCaptureTakeFromBuffer(BYTE pBuf[], int iSize, WAVEFORMATEX* ifNotNullThenJustSetTypeOnly, LONG* sizeWrote);\r\n\r\n#define BITS_PER_BYTE 8\r\n\r\n#define VIRTUAL_AUDIO_VERSION L\"0.6.0\"\r\n\r\nvoid LoopbackCaptureClear();\r\n\r\nHRESULT get_default_device(IMMDevice **ppMMDevice);"
  },
  {
    "path": "source_code/acam/directshow_fillbuffer.cpp",
    "content": "#include \"stdafx.h\"\r\n#include \"acam.h\"\r\n\r\n\r\nCCritSec gSharedState;\r\n\r\nextern int totalBlips;\r\n//\r\n// FillBuffer\r\n//\r\n// Stuffs the buffer with data\r\n// \"they\" call this, every so often...\r\nHRESULT CVCamStream::FillBuffer(IMediaSample *pms) \r\n{\t\r\n\t// I don't expect these...the parent controls this/us and doesn't call us when it is stopped I guess, so we should always be active...\r\n\tShowOutput(\"downstream requested an audio frame (FillBuffer cal led)\");\r\n\t//assert(m_pParent->IsActive()); // one of these can cause freezing on \"stop button\" in FME\r\n\t//assert(!m_pParent->IsStopped());\r\n\t\r\n    CheckPointer(pms, E_POINTER);\r\n    BYTE *pData;\r\n    HRESULT hr = pms->GetPointer(&pData);\r\n    if (FAILED(hr)) {\r\n\t\tassert(false);\r\n        return hr;\r\n    }\r\n\r\n\t// allow it to warmup until Run is called...so StreamTime can work right (ai ai) see http://stackoverflow.com/questions/2469855/how-to-get-imediacontrol-run-to-start-a-file-playing-with-no-delay/2470548#2470548\r\n\tFILTER_STATE myState;\r\n\tCSourceStream::m_pFilter->GetState(INFINITE, &myState); // get parent filter state which is only set to Run \"after pause\" etc.\r\n\twhile(myState != State_Running) {\r\n\t\tShowOutput(\"sleeping till graph running for audio...\");\r\n\t\tShowOutput(\"clearing loop back capture buffer\"); // why have extra from \"during\" the paused state? just trash it! :)\r\n   \t    LoopbackCaptureClear(); // could stop and restart it I guess here, too...in theory...but that seems a bit violent and this more the \"dshow way of doing things\"\r\n\t\t// also sets bVeryFirstPacket\r\n\t\tSleep(1);\r\n\t\tCommand com;\r\n        if(CheckRequest(&com)) { // from http://microsoft.public.multimedia.directx.dshow.programming.narkive.com/h8ZxbM9E/csourcestream-fillbuffer-timing\r\n          if(com == CMD_STOP) {\r\n\t\t\t  ShowOutput(\"exiting early from CMD_STOP thinger\");\r\n              return S_FALSE;\r\n\t\t  }\r\n        }\r\n\t\tm_pParent->GetState(INFINITE, &myState);  \r\n\t}\r\n\r\n\tif (bVeryFirstPacket)\r\n\t  LoopbackCaptureClear(); // this is to recover from pause resumes :|\r\n\r\n\t// the real meat -- get all the incoming audio data\r\n\tLONG totalWrote = -1;\r\n\thr = LoopbackCaptureTakeFromBuffer(pData, pms->GetSize(), NULL, &totalWrote);\r\n\tif(FAILED(hr)) {\r\n\t\t// this one can return false during shutdown, so it's actually ok to just return from here...\r\n\t\t// assert(false);\r\n\t\tShowOutput(\"capture failed 1\");\r\n\t\treturn hr; \r\n\t\t// don't return false here or people may get a \"the graph was unable to change state unspecified error return code: 0x80004005) when hitting the stop button in graphedit :|\r\n\t\t// which actually occurs during shutdown...not sure what to really do here...\r\n\t\t//pms->SetActualDataLength(0);\r\n\t\t//return S_OK;\r\n\t\t// except we *want* the graph to abort if they've unplugged something hrm...\r\n\t}\r\n\r\n\tCAutoLock cAutoLockShared(&gSharedState); // for the bFirstPacket boolean control, except there's probably still some odd race conditions er other...\r\n\thr = pms->SetActualDataLength(totalWrote);\r\n\tif(FAILED(hr)) {\r\n  \t  \tassert(false);\r\n\t\t//return hr;\r\n\t}\r\n\r\n    // Now set the sample's start and end time stamps...\r\n\t\r\n\tWAVEFORMATEX* pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();\r\n\tCRefTime sampleTimeUsed = (REFERENCE_TIME)(UNITS * totalWrote) / \r\n                     (REFERENCE_TIME)pwfexCurrent->nAvgBytesPerSec;\r\n    CRefTime rtStart;\r\n\tif(bDiscontinuityDetected || bVeryFirstPacket) { // could either use bFirstPacket or true here...true seemed to help that one guy...\r\n      CSourceStream::m_pFilter->StreamTime(rtStart); // this is (zero based clock_time if Run already called) but we don't have access to start_offset, and want (just clock time) so don't use it... :|\t  \r\n\t  if(bDiscontinuityDetected && !bVeryFirstPacket) {\r\n\t    ShowOutput(\"audio discontinuity detected\");\r\n\t  }\r\n\t  if(bVeryFirstPacket) {\r\n\t\t  // my theory is that sometimes the very first packet is \"big\" and there's tons there [slow ffmpeg startup for instance, or something like that] and it would mess up our timing to say that it \"starts\" now and goes \"until\" its end\r\n\t\t  rtStart -= sampleTimeUsed; // so instruct it to think this frame started slightly in the past...\r\n\t\t  // in an effort to try and avoid some async issues\r\n\t\t  ShowOutput(\"initial very first packet size %I64d\", sampleTimeUsed);\r\n\t  } else if (bDiscontinuityDetected) {\r\n\t\t  // same deal [as if I knew what I were doing...LOL]\r\n\t\t  rtStart = MAX(m_rtPreviousSampleEndTime, rtStart - sampleTimeUsed);\r\n\t  }\r\n\t} else {\r\n\t\t// since there hasn't been discontinuity, I think we should be safe to tell it\r\n\t\t// that this packet starts where the previous packet ended off\r\n\t\t// since that's theoretically accurate...\r\n\t\t// exept that it ends up being bad [?]\r\n\t\t// I don't \"think\" this will hurt graphs that have no reference clock...hopefully...\r\n\r\n\t\trtStart = m_rtPreviousSampleEndTime;\r\n\r\n        // CRefTime cur_time;\r\n\t    // m_pParent->StreamTime(cur_time);\r\n\t    // rtStart = max(rtStart, cur_time);\r\n\t\t// hopefully this being commented out avoids this message/error:\r\n\t\t// [libmp3lame @ 00670aa0] Que input is backward in time\r\n        // Audio timestamp 329016 < 329026 invalid, cliping 00:05:29.05 bitrate= 738.6kbits/s\r\n        // [libmp3lame @ 00670aa0] Que input is backward in time\r\n\t}\r\n\r\n\t// I once tried to change it to always have monotonicity of timestamps at this point, but it didn't fix any problems, and seems to do all right without it so maybe ok [?]\r\n    m_rtPreviousSampleEndTime = rtStart + sampleTimeUsed;\r\n\r\n\t// attempt to disallow drift/keep these in sync :|\r\n\tCRefTime now;\r\n    CSourceStream::m_pFilter->StreamTime(now);\r\n    CRefTime diff = now - m_rtPreviousSampleEndTime;\r\n    if (diff > 0)\r\n        m_rtPreviousSampleEndTime += CRefTime((long)1);\r\n    else if (diff < -100000)\r\n        m_rtPreviousSampleEndTime -= CRefTime((long)1);\r\n\r\n\t// NB that this *can* set it to a negative start time...hmm...which apparently is \"ok\" when a graph is just starting up it's expected...\r\n\tShowOutput(\"timestamping audio packet as %lld -> %lld\", rtStart, m_rtPreviousSampleEndTime);\r\n    hr = pms->SetTime((REFERENCE_TIME*) &rtStart, (REFERENCE_TIME*) &m_rtPreviousSampleEndTime);\r\n\tif (FAILED(hr)) {\r\n\t\tassert(false);\r\n        //return hr;\r\n    }\r\n\t// if we do SetTime(NULL, NULL) here then VLC can \"play\" it with directshows buffers of size 0ms.\r\n\t// however, then VLC cannot then stream it at all.  So we leave it set to some time, and just require you to have VLC buffers of at least 40 or 50 ms\r\n\t// [a possible VLC bug?] http://forum.videolan.org/viewtopic.php?f=14&t=92659&hilit=+50ms\r\n\r\n\t// whatever SetMediaTime even means...\r\n    // hr = pms->SetMediaTime((REFERENCE_TIME*)&rtStart, (REFERENCE_TIME*)&m_rtPreviousSampleEndTime);\r\n    //m_llSampleMediaTimeStart = m_rtSampleEndTime;\r\n\r\n\tif (FAILED(hr)) {\r\n\t\tassert(false);\r\n        //return hr;\r\n    }\r\n\r\n    // Set the sample's properties.\r\n    hr = pms->SetPreroll(FALSE); // tell it that this isn't preroll, so to actually use it...I think.\r\n    if (FAILED(hr)) {\r\n\t\tassert(false);\r\n        //return hr;\r\n    }\r\n\r\n    hr = pms->SetMediaType(NULL);\r\n    if (FAILED(hr)) {\r\n\t\tassert(false);\r\n        //return hr;\r\n    }\r\n   \r\n    hr = pms->SetDiscontinuity(bDiscontinuityDetected || bVeryFirstPacket);\r\n    if (FAILED(hr)) {\r\n\t\tassert(false);\r\n        //return hr;\r\n    }\r\n    \r\n\t// Set TRUE on every sample for PCM audio http://msdn.microsoft.com/en-us/library/windows/desktop/dd407021%28v=vs.85%29.aspx\r\n    hr = pms->SetSyncPoint(TRUE);\r\n\tif (FAILED(hr)) {\r\n\t\tassert(false);\r\n        return hr;\r\n    }\r\n\tFILTER_STATE State;\r\n\tm_pParent->GetState(0, &State);\r\n\t\r\n    bDiscontinuityDetected = false; // reset late since I use it for the SetDiscontinuity method\r\n\tbVeryFirstPacket = false;\r\n\r\n\tShowOutput(\"sent audio frame, %d blips, filter state %d\", totalBlips, State);\r\n    return S_OK;\r\n\r\n} // end FillBuffer\r\n"
  },
  {
    "path": "source_code/acam/directshow_stuff.cpp",
    "content": "#include \"stdafx.h\"\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n//  This file contains routines to register / Unregister the \r\n//  Directshow filter 'Virtual Cam'\r\n//  We do not use the inbuilt BaseClasses routines as we need to register as\r\n//  a capture source\r\n//////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n#include <streams.h>\r\n#include <dllsetup.h>\r\n#include <stdio.h>\r\n#include \"acam.h\"\r\n\r\n#pragma once\r\n\r\n#define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr);\r\n\r\nextern long expectedMaxBufferSize;\r\nextern long pBufOriginalSize; \r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n//  CVCam is the source filter which masquerades as a capture device\r\n//////////////////////////////////////////////////////////////////////////\r\nCUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)\r\n{\r\n    ASSERT(phr);\r\n    CUnknown *punk = new CVCam(lpunk, phr);\r\n\r\n\treturn punk;\r\n}\r\n\r\nIReferenceClock *globalClock;\r\n\r\nCVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) : \r\n    CSource(NAME(\"Virtual cam5\"), lpunk, CLSID_VirtualCam)\r\n{\r\n    ASSERT(phr);\r\n\t//m_pClock is null at this point...\r\n    m_paStreams = (CSourceStream **) new CVCamStream*[1];\r\n    m_paStreams[0] = new CVCamStream(phr, this, L\"Capture Virtual Audio Pin\");\r\n}\r\n\r\nHRESULT CVCam::QueryInterface(REFIID riid, void **ppv)\r\n{\r\n    //Forward request for IAMStreamConfig & IKsPropertySet to the pin\r\n    if(riid == _uuidof(IAMStreamConfig) || riid == _uuidof(IKsPropertySet))\r\n        return m_paStreams[0]->QueryInterface(riid, ppv);\r\n    else\r\n        return CSource::QueryInterface(riid, ppv);\r\n}\r\n\r\n// this does seem to get called frequently... http://msdn.microsoft.com/en-us/library/dd377472%28v=vs.85%29.aspx\r\n// I believe theoretically return VFW_S_CANT_CUE means \"don't call me for data\" so we should be safe here [?] but somehow still FillBuffer is called :|\r\nSTDMETHODIMP CVCam::GetState(DWORD dw, FILTER_STATE *pState)\r\n{\r\n\t//ShowOutput(\"GetState call ed\");\r\n    CheckPointer(pState, E_POINTER);\r\n    *pState = m_State;\r\n    if (m_State == State_Paused)\r\n    {\r\n        return VFW_S_CANT_CUE;\r\n    }\r\n    else\r\n    {\r\n        return S_OK;\r\n    }\r\n}\r\n\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n// CVCamStream is the one and only output pin of CVCam which handles \r\n// all the stuff.\r\n//////////////////////////////////////////////////////////////////////////\r\nCVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :\r\n    CSourceStream(NAME(\"Virtual cam5\"),phr, pParent, pPinName), m_pParent(pParent)\r\n{\r\n    // Set the default media type...\r\n\tGetMediaType(0, &m_mt);\r\n}\r\n\r\nvoid loopBackRelease();\r\n\r\nCVCamStream::~CVCamStream()\r\n{\r\n\t// don't get here with any consistency...\r\n\tShowOutput(\"destructor\");\r\n} \r\n\r\n// these latency/pushsource stuffs never seem to get called...ever...at least by VLC...\r\n/* therefore unimplemented yet...\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetLatency(REFERENCE_TIME *storeItHere) {\r\n\t*storeItHere = 10000/SECOND_FRACTIONS_TO_GRAB;\r\n\t// 1_000_000ns per s, this is in 100 ns or 10_000/s\r\n\treturn S_OK;\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetPushSourceFlags(ULONG *storeHere) {\r\n\tstoreHere = 0; // the default (0) is ok...\r\n\treturn S_OK;\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::SetPushSourceFlags(ULONG storeHere) {\r\n\treturn E_UNEXPECTED; // shouldn't ever call this...\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetStreamOffset(REFERENCE_TIME *toHere) {\r\n\treturn E_UNEXPECTED; // shouldn't ever call this...\r\n\r\n//  *toHere = m_tStart; // guess this is right... huh? offset? to what?\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetMaxStreamOffset(REFERENCE_TIME *toHere) {\r\n  *toHere = 0; // TODO set this to a reasonable value...\r\n  return S_OK;\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::SetMaxStreamOffset(REFERENCE_TIME) {\r\n\treturn E_UNEXPECTED; // I don't think they'd ever call this either...\r\n}*/\r\n\r\nHRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)\r\n{   \r\n    // Standard OLE stuff...allow it to query for our interfaces that we implement...\r\n    if(riid == _uuidof(IAMStreamConfig))\r\n        *ppv = (IAMStreamConfig*)this;\r\n    else if(riid == _uuidof(IKsPropertySet))\r\n        *ppv = (IKsPropertySet*)this;\r\n\telse if(riid == _uuidof(IAMBufferNegotiation))\r\n\t\t *ppv = (IAMBufferNegotiation*)this;\r\n    else\r\n        return CSourceStream::QueryInterface(riid, ppv);\r\n\r\n    AddRef();\r\n    return S_OK;\r\n}\r\n\r\n//\r\n// Notify\r\n// Ignore quality management messages sent from the downstream filter\r\nSTDMETHODIMP CVCamStream::Notify(IBaseFilter * pSender, Quality q)\r\n{\r\n    return E_NOTIMPL;\r\n} // Notify\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n// This is called when the output format has been negotiated\r\n//////////////////////////////////////////////////////////////////////////\r\nHRESULT CVCamStream::SetMediaType(const CMediaType *pmt)\r\n{\r\n\t// call the base class' SetMediaType...\r\n    HRESULT hr = CSourceStream::SetMediaType(pmt);\r\n    return hr;\r\n}\r\n\r\nHRESULT setupPwfex(WAVEFORMATEX *pwfex, AM_MEDIA_TYPE *pmt) { // called super early during negotiation...\r\n\t// we prefer PCM since WAVE_FORMAT_EXTENSIBLE seems to cause IFilterGraph::DirectConnect to fail, and many programs use it [VLC maybe does?]\r\n\t// also we set it up to auto convert to PCM for us\r\n\t// see also the bInt16 setting\r\n\tpwfex->wFormatTag = WAVE_FORMAT_PCM;\r\n\tpwfex->cbSize = 0;                  // apparently should be zero if using WAVE_FORMAT_PCM http://msdn.microsoft.com/en-us/library/ff538799(VS.85).aspx\r\n\tpwfex->nChannels = getChannels();               // 1 for mono, 2 for stereo..\r\n\tHRESULT hr;\r\n\tpwfex->nSamplesPerSec = getHtzRate(&hr);\r\n\tif (hr != S_OK) {\r\n\t\treturn hr;\r\n\t}\r\n\tpwfex->wBitsPerSample = 16;          // 16 bit sound\r\n\tpwfex->nBlockAlign = (WORD)((pwfex->wBitsPerSample * pwfex->nChannels) / BITS_PER_BYTE);\r\n\tpwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign; // it can't calculate this itself? huh?\r\n\t\t\r\n\t// copy this info into the pmt\r\n    hr = ::CreateAudioMediaType(pwfex, pmt, FALSE /* dont allocate more memory */);\r\n\treturn hr;\r\n}\r\n\r\nHRESULT CVCamStream::setAsNormal(CMediaType *pmt) {\r\n  WAVEFORMATEX *pwfex;\r\n  pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));\r\n  ZeroMemory(pwfex, sizeof(WAVEFORMATEX));\r\n  if(NULL == pwfex)\r\n   {\r\n       return E_OUTOFMEMORY;\r\n   }\r\n   return setupPwfex(pwfex, pmt);\r\n}\r\n\r\n// GetMediaType\r\n// I believe \"they\" call this...\r\n// we only have one type at a time...\r\n// so we just return our one type...\r\n// which we already told them what it was.\r\nHRESULT CVCamStream::GetMediaType(int iPosition, CMediaType *pmt) \r\n{\r\n    if (iPosition < 0) {\r\n        return E_INVALIDARG;\r\n    }\r\n\r\n\tif (iPosition > 0) {\r\n        return VFW_S_NO_MORE_ITEMS;\r\n\t}\r\n\r\n    WAVEFORMATEX *pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));\r\n\t\r\n\tsetupPwfex(pwfex, pmt);\r\n\treturn S_OK;\r\n}\r\n\r\n// This method is called to see if a given output format is supported\r\nHRESULT CVCamStream::CheckMediaType(const CMediaType *pMediaType)\r\n{\r\n\tint cbFormat = pMediaType->cbFormat;\r\n    if(*pMediaType != m_mt) {\r\n        return E_INVALIDARG;\r\n\t}\r\n    return S_OK;\r\n} // CheckMediaType\r\n\r\n\r\n// Size of each allocated buffer\r\n// seems arbitrary\r\n// maybe downstream needs a certain size?\r\nconst int WaveBufferChunkSize = 16*1024;     \r\n\r\n// DecideBufferSize\r\n//\r\n// This will always be called after the format has been sucessfully\r\n// negotiated. So we have a look at m_mt to see what format we agreed to.\r\n// Then we can ask for buffers of the correct size to contain them.\r\nHRESULT CVCamStream::DecideBufferSize(IMemAllocator *pAlloc,\r\n                                       ALLOCATOR_PROPERTIES *pProperties)\r\n{\r\n    CheckPointer(pAlloc,E_POINTER);\r\n    CheckPointer(pProperties,E_POINTER);\r\n\r\n    WAVEFORMATEX *pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();\r\n\r\n\t// just use our max size for the buffer size (or whatever they specified for us, if they did)\r\n\tpProperties->cBuffers = 1;\r\n\tpProperties->cbBuffer = expectedMaxBufferSize;\r\n\r\n    // Ask the allocator to reserve us this much memory...\r\n\t\r\n    ALLOCATOR_PROPERTIES Actual;\r\n    HRESULT hr = pAlloc->SetProperties(pProperties, &Actual);\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    // Is this allocator unsuitable\r\n\r\n    if(Actual.cbBuffer < pProperties->cbBuffer)\r\n    {\r\n        return E_FAIL;\r\n    }\r\n\r\n    return NOERROR;\r\n\r\n} // DecideBufferSize\r\n\r\nHRESULT LoopbackCaptureSetup();\r\n\r\nHRESULT CVCamStream::OnThreadDestroy()\r\n{\r\n\tShowOutput(\"OnThreadDestroy\");\r\n\treturn S_OK; \r\n}\r\n\r\n//less useful, for VLC anyway..\r\nHRESULT CVCamStream::Stop()\r\n{\r\n\t// never get here\r\n\tShowOutput(\"pin stop called\");\r\n\t// call Inactive to initiate shutdown anyway just in case :)\r\n\tInactive();\r\n\treturn S_OK;\r\n}\r\n\r\nHRESULT CVCamStream::Exit()\r\n{\r\n\t// never seem to get here\r\n    ShowOutput(\"exit called\");\r\n\treturn S_OK;\r\n}\r\n\r\nint currentlyRunning = 0;\r\n\r\nHRESULT CVCamStream::Inactive()\r\n{\r\n\t// we get here at least with vlc\r\n\tShowOutput(\"stream inactive called\");\r\n\treturn CSourceStream::Inactive(); //parent method\r\n}\r\n\r\nSTDMETHODIMP CVCam::Stop()\r\n{\r\n\tShowOutput(\"parent stop called\");\r\n\tif (currentlyRunning)\r\n\t{\r\n      ShowOutput(\"about to release loopback\");\r\n\t  loopBackRelease();\r\n\t  ShowOutput(\"loopback released\");\r\n  \t  currentlyRunning = 0; // allow it to restart later...untested...\r\n\t}\r\n\r\n\treturn CSource::Stop();\r\n}\r\n\r\nSTDMETHODIMP CVCam::Pause()\r\n{\r\n\t// pause also gets called at \"graph setup\" time somehow before an initial Run, and always, weirdly...\r\n\t// but not at \"teardown\" or \"stop\" time apparently...\r\n\t// but yes at \"pause\" time as it were (though some requests for packets still occur, even after that, yikes!)\r\n\t// pause is also called immediately before Stop...yikes!\r\n\t// so the order is pause, run, pause, stop\r\n\t// or, with a pause in there\r\n\t// pause, run, pause, run, pause, stop\r\n\t// or have I seen run pause before, initially [?] ai ai\r\n\t// unfortunately after each pause it still \"requires\" a few samples out or the graph will die (well, as we're doing it ???)\r\n\t// see also http://microsoft.public.multimedia.directx.dshow.programming.narkive.com/h8ZxbM9E/csourcestream-fillbuffer-timing this thing shucks..huh?\r\n\t// so current plan: just start it once, leave it going...but when Run is called it clears a buffer somewhere...\r\n\tShowOutput(\"parent pause called\");\r\n\treturn CBaseFilter::Pause();\r\n}\r\n\r\n// Called when graph is first started\r\nHRESULT CVCamStream::OnThreadCreate()\r\n{\r\n\tShowOutput(\"OnThreadCreate called\"); // seems like this gets called pretty early...\r\n    GetMediaType(0, &m_mt); // give it a default type...do we even  need this? LOL\r\n\r\n\tassert(currentlyRunning == 0); // sanity check no double starts...\r\n\tcurrentlyRunning = TRUE;\r\n\r\n    HRESULT hr = LoopbackCaptureSetup();\r\n    if (FAILED(hr)) {\r\n       printf(\"IAudioCaptureClient::setup failed\");\r\n       return hr;\r\n    }\r\n\r\n    return NOERROR;\r\n}\r\nvoid LoopbackCaptureClear();\r\nSTDMETHODIMP CVCam::Run(REFERENCE_TIME tStart) {\r\n\tShowOutput(\"Parent Run called\");\r\n\tLoopbackCaptureClear(); // post pause, want to clear this to alert it to use the right time stamps...I think hope!\r\n\r\n\t// LODO why is this called seemingly *way* later than packets are already collected? I guess it calls Pause first or something, to let filters \"warm up\" ... so in essence, this means \"unPause! go!\"\r\n\t// ((CVCamStream*) m_paStreams[0])->m_rtPreviousSampleEndTime = 0;\r\n\t// looks like we accomodate for \"resetting\" within our own discontinuity stuff...\r\n\t// LODO should we...umm...not give any samples before second one or not here?\r\n\treturn CSource::Run(tStart); // this just calls CBaseFilter::Run (which calls Run on all the pins *then* sets its state to running)\r\n}\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n//  IAMStreamConfig\r\n//////////////////////////////////////////////////////////////////////////\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt)\r\n{\r\n\t// this is them saying you \"must\" use this type from now on...unless pmt is NULL that \"means\" reset...LODO handle it someday...\r\n\tif(!pmt) {\r\n\t  return S_OK; // *sure* we reset..yeah...sure we did...\r\n\t}\r\n\t\r\n   if(CheckMediaType((CMediaType *) pmt) != S_OK) {\r\n\treturn E_FAIL; // just in case :P [FME...]\r\n   }\r\n\t\r\n\tm_mt = *pmt;\r\n\r\n\tIPin* pin; \r\n\tConnectedTo(&pin);\r\n\tif(pin)\r\n\t{\r\n\t\tIFilterGraph *pGraph = m_pParent->GetGraph();\r\n\t\tpGraph->Reconnect(this);\r\n\t}\r\n\r\n    return S_OK;\r\n}\r\n\r\n// set format or \"preferred\" format if none set.  It's all always the same for us, and was already set to it.\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetFormat(AM_MEDIA_TYPE **ppmt)\r\n{\r\n    *ppmt = CreateMediaType(&m_mt);\r\n    return S_OK;\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetNumberOfCapabilities(int *piCount, int *piSize)\r\n{\r\n    *piCount = 1; // only allow one type currently...\r\n    *piSize = sizeof(AUDIO_STREAM_CONFIG_CAPS);\r\n    return S_OK;\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetStreamCaps(int iIndex, AM_MEDIA_TYPE **ppMediaType, BYTE *pSCC)\r\n{\t \r\n\t\r\n\tif(iIndex < 0)\r\n\t\treturn E_INVALIDARG;\r\n\tif(iIndex > 0)\r\n\t\treturn S_FALSE;\r\n\tif(pSCC == NULL)\r\n\t\treturn E_POINTER;\r\n\r\n    *ppMediaType = CreateMediaType(&m_mt);\r\n\tif (*ppMediaType == NULL) return E_OUTOFMEMORY;\r\n\r\n    DECLARE_PTR(WAVEFORMATEX, pAudioFormat, (*ppMediaType)->pbFormat);\r\n\t\r\n\tAM_MEDIA_TYPE * pm = *ppMediaType;\r\n\t\r\n\tsetupPwfex(pAudioFormat, pm);\r\n\r\n\tAUDIO_STREAM_CONFIG_CAPS* pASCC = (AUDIO_STREAM_CONFIG_CAPS*) pSCC;\r\n\tZeroMemory(pSCC, sizeof(AUDIO_STREAM_CONFIG_CAPS)); \r\n\r\n\t// Set up audio capabilities [one type only, for now]\r\n\tpASCC->guid = MEDIATYPE_Audio;\r\n\tpASCC->MaximumChannels = pAudioFormat->nChannels;\r\n\tpASCC->MinimumChannels = pAudioFormat->nChannels;\r\n\tpASCC->ChannelsGranularity = 1; // doesn't matter\r\n\tpASCC->MaximumSampleFrequency = pAudioFormat->nSamplesPerSec;\r\n\tpASCC->MinimumSampleFrequency = pAudioFormat->nSamplesPerSec;\r\n\tpASCC->SampleFrequencyGranularity = 11025; // doesn't matter\r\n\tpASCC->MaximumBitsPerSample = pAudioFormat->wBitsPerSample;\r\n\tpASCC->MinimumBitsPerSample = pAudioFormat->wBitsPerSample;\r\n\tpASCC->BitsPerSampleGranularity = 16; // doesn't matter\r\n\r\n\treturn S_OK;\r\n}\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n// IKsPropertySet\r\n//////////////////////////////////////////////////////////////////////////\r\n\r\nHRESULT CVCamStream::Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, \r\n                        DWORD cbInstanceData, void *pPropData, DWORD cbPropData)\r\n{// Set: Cannot set any properties.\r\n    return E_NOTIMPL;\r\n}\r\n\r\n// Get: Return the pin category (our only property). \r\nHRESULT CVCamStream::Get(\r\n    REFGUID guidPropSet,   // Which property set.\r\n    DWORD dwPropID,        // Which property in that set.\r\n    void *pInstanceData,   // Instance data (ignore).\r\n    DWORD cbInstanceData,  // Size of the instance data (ignore).\r\n    void *pPropData,       // Buffer to receive the property data.\r\n    DWORD cbPropData,      // Size of the buffer.\r\n    DWORD *pcbReturned     // Return the size of the property.\r\n)\r\n{\r\n    if (guidPropSet != AMPROPSETID_Pin)             return E_PROP_SET_UNSUPPORTED;\r\n    if (dwPropID != AMPROPERTY_PIN_CATEGORY)        return E_PROP_ID_UNSUPPORTED;\r\n    if (pPropData == NULL && pcbReturned == NULL)   return E_POINTER;\r\n    \r\n    if (pcbReturned) *pcbReturned = sizeof(GUID);\r\n    if (pPropData == NULL)          return S_OK; // Caller just wants to know the size. \r\n    if (cbPropData < sizeof(GUID))  return E_UNEXPECTED;// The buffer is too small.\r\n        \r\n    *(GUID *)pPropData = PIN_CATEGORY_CAPTURE;\r\n    return S_OK;\r\n}\r\n\r\n// QuerySupported: Query whether the pin supports the specified property.\r\nHRESULT CVCamStream::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport)\r\n{\r\n    if (guidPropSet != AMPROPSETID_Pin) return E_PROP_SET_UNSUPPORTED;\r\n    if (dwPropID != AMPROPERTY_PIN_CATEGORY) return E_PROP_ID_UNSUPPORTED;\r\n    // We support getting this property, but not setting it.\r\n    if (pTypeSupport) *pTypeSupport = KSPROPERTY_SUPPORT_GET; \r\n    return S_OK;\r\n}\r\n\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::SuggestAllocatorProperties( /* [in] */ const ALLOCATOR_PROPERTIES *pprop) {\r\n\t// maybe we shouldn't even care though...I mean like seriously...why let them make it smaller <sigh>\r\n\t// LODO test it both ways with FME, fast computer/slow computer does it make a difference?\r\n\tint requested = pprop->cbBuffer;\r\n\tif(pprop->cBuffers > 0)\r\n\t    requested *= pprop->cBuffers;\r\n\tif(pprop->cbPrefix > 0)\r\n\t    requested += pprop->cbPrefix;\r\n\t\r\n\tif(requested <= pBufOriginalSize) {\r\n \t\texpectedMaxBufferSize = requested;\r\n\t\treturn S_OK; // they requested it? ok you got it! You're requesting possible problems! oh well! you requested it!\r\n\t} else {\r\n\t\treturn E_FAIL;\r\n\t}\r\n}\r\n\r\nHRESULT STDMETHODCALLTYPE CVCamStream::GetAllocatorProperties( ALLOCATOR_PROPERTIES *pprop) {return NULL;} // they never call this...\r\n"
  },
  {
    "path": "source_code/acam/dll_main.cpp",
    "content": "// dllmain.cpp : Defines the entry point for the DLL application.\r\n#include \"stdafx.h\"\r\n#include <olectl.h>\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n//  This file contains routines to register / Unregister the \r\n//  Directshow filter 'Virtual Cam'\r\n//  We do not use the inbuilt BaseClasses routines as we need to register as\r\n//  a capture source\r\n//////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n#include <streams.h>\r\n#include <initguid.h>\r\n#include <dllsetup.h>\r\n#include <stdio.h>\r\n\r\n\r\n\r\n#pragma comment(lib, \"kernel32\")\r\n#pragma comment(lib, \"user32\")\r\n#pragma comment(lib, \"gdi32\")\r\n#pragma comment(lib, \"advapi32\")\r\n#pragma comment(lib, \"winmm\")\r\n#pragma comment(lib, \"ole32\")\r\n#pragma comment(lib, \"oleaut32\")\r\n\r\n#ifdef _DEBUG\r\n    #pragma comment(lib, \"strmbasd\")\r\n#else\r\n    #pragma comment(lib, \"strmbase\")\r\n#endif\r\n\r\n#include <olectl.h>\r\n#include <initguid.h> // can only include this once/project\r\n#include <dllsetup.h>\r\n#include \"acam.h\"\r\n\r\n#define CreateComObject(clsid, iid, var) CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&var);\r\n\r\nSTDAPI AMovieSetupRegisterServer( CLSID   clsServer, LPCWSTR szDescription, LPCWSTR szFileName, LPCWSTR szThreadingModel = L\"Both\", LPCWSTR szServerType     = L\"InprocServer32\" );\r\nSTDAPI AMovieSetupUnregisterServer( CLSID clsServer );\r\n\r\n#ifdef _WIN64\r\n// was {8E14549A-DB61-4309-AFA1-3578E927E933}\r\n// {8E14549B-DB61-4309-AFA1-3578E927E935} now...\r\nDEFINE_GUID(CLSID_VirtualCam,\r\n            0x8e146464, 0xdb61, 0x4309, 0xaf, 0xa1, 0x35, 0x78, 0xe9, 0x27, 0xe9, 0x35);\r\n#else\r\n// was {8E14549A-DB61-4309-AFA1-3578E927E933}\r\n// {8E14549B-DB61-4309-AFA1-3578E927E935} now...\r\nDEFINE_GUID(CLSID_VirtualCam,\r\n            0x8e14549b, 0xdb61, 0x4309, 0xaf, 0xa1, 0x35, 0x78, 0xe9, 0x27, 0xe9, 0x35);\r\n#endif\r\n\r\nconst AMOVIESETUP_MEDIATYPE AMSMediaTypesVCam = \r\n{ &MEDIATYPE_Audio      // clsMajorType\r\n, &MEDIASUBTYPE_NULL }; // clsMinorType\r\n\r\nconst AMOVIESETUP_PIN AMSPinVCam=\r\n{\r\n    L\"Output\",             // Pin string name\r\n    FALSE,                 // Is it rendered\r\n    TRUE,                  // Is it an output\r\n    FALSE,                 // Can we have none\r\n    FALSE,                 // Can we have many\r\n    &CLSID_NULL,           // Connects to filter\r\n    NULL,                  // Connects to pin\r\n    1,                     // Number of types\r\n    &AMSMediaTypesVCam      // Pin Media types\r\n};\r\n\r\nconst AMOVIESETUP_FILTER AMSFilterVCam =\r\n{\r\n    &CLSID_VirtualCam,  // Filter CLSID\r\n    L\"virtual-audio-capturer\",     // String name\r\n    MERIT_DO_NOT_USE,      // Filter merit\r\n    1,                     // Number pins\r\n    &AMSPinVCam             // Pin details\r\n};\r\n\r\nCFactoryTemplate g_Templates[] = \r\n{\r\n    {\r\n        L\"virtual-audio-capturer\",\r\n        &CLSID_VirtualCam,\r\n        CVCam::CreateInstance,\r\n        NULL,\r\n        &AMSFilterVCam\r\n    },\r\n\r\n};\r\n\r\nint g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);\r\n\r\n// straight call to here on init, instead of to\r\n// AMovieDllRegisterServer2 which is what the other fella does...\r\n// which I assume is similar to this...maybe?\r\nSTDAPI RegisterFilters( BOOL bRegister )\r\n{\r\n    HRESULT hr = NOERROR;\r\n    WCHAR achFileName[MAX_PATH];\r\n    char achTemp[MAX_PATH];\r\n    ASSERT(g_hInst != 0);\r\n\r\n    if( 0 == GetModuleFileNameA(g_hInst, achTemp, sizeof(achTemp))) \r\n        return AmHresultFromWin32(GetLastError());\r\n\r\n    MultiByteToWideChar(CP_ACP, 0L, achTemp, lstrlenA(achTemp) + 1, \r\n                       achFileName, NUMELMS(achFileName));\r\n  \r\n    hr = CoInitialize(0);\r\n    if(bRegister)\r\n    {\r\n        hr = AMovieSetupRegisterServer(CLSID_VirtualCam, L\"virtual-audio-capturer\", achFileName, L\"Both\", L\"InprocServer32\");\r\n    }\r\n\r\n    if( SUCCEEDED(hr) )\r\n    {\r\n        IFilterMapper2 *fm = 0;\r\n        hr = CreateComObject( CLSID_FilterMapper2, IID_IFilterMapper2, fm );\r\n        if( SUCCEEDED(hr) )\r\n        {\r\n            if(bRegister)\r\n            {\r\n                IMoniker *pMoniker = 0;\r\n                REGFILTER2 rf2;\r\n                rf2.dwVersion = 1;\r\n                rf2.dwMerit = MERIT_DO_NOT_USE;\r\n                rf2.cPins = 1;\r\n                rf2.rgPins = &AMSPinVCam;\r\n                hr = fm->RegisterFilter(CLSID_VirtualCam, L\"virtual-audio-capturer\", &pMoniker, &CLSID_AudioInputDeviceCategory, NULL, &rf2);\r\n            }\r\n            else\r\n            {\r\n                hr = fm->UnregisterFilter(&CLSID_AudioInputDeviceCategory, 0, CLSID_VirtualCam);\r\n            }\r\n        }\r\n\r\n      // release interface\r\n      if(fm)\r\n          fm->Release();\r\n    }\r\n\r\n    if( SUCCEEDED(hr) && !bRegister )\r\n        hr = AMovieSetupUnregisterServer( CLSID_VirtualCam );\r\n\r\n    CoFreeUnusedLibraries();\r\n    CoUninitialize();\r\n    return hr;\r\n}\r\n\r\n// DLL.cpp\r\n\r\n//////////////////////////////////////////////////////////////////////////\r\n//  This file contains routines to register / Unregister the \r\n//  Directshow filter 'Virtual Cam'\r\n//  We do not use the inbuilt BaseClasses routines as we need to register as\r\n//  a capture source\r\n//////////////////////////////////////////////////////////////////////////\r\n#include <stdio.h>\r\n\r\nSTDAPI RegisterFilters( BOOL bRegister );\r\n\r\nSTDAPI DllRegisterServer()\r\n{\r\n\tprintf(\"hello there\"); // we actually never see this...\r\n    return RegisterFilters(TRUE);\r\n}\r\n\r\nSTDAPI DllUnregisterServer()\r\n{\r\n    return RegisterFilters(FALSE);\r\n}\r\n\r\nSTDAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);\r\n\r\nextern \"C\" BOOL APIENTRY DllMain(HANDLE hModule, DWORD  dwReason, LPVOID lpReserved)\r\n{\r\n\treturn DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);\r\n}\r\n\r\n"
  },
  {
    "path": "source_code/acam/loopback-capture-helpers.cpp",
    "content": "#include \"stdafx.h\"\r\n\r\n#include <windows.h>\r\n#include <mmsystem.h>\r\n#include <mmdeviceapi.h>\r\n#include <audioclient.h>\r\n#include <stdio.h>\r\n#include <avrt.h>\r\n\r\n// I guess this is the default...audio output device...\r\nHRESULT get_default_device(IMMDevice **ppMMDevice) {\r\n    HRESULT hr;\r\n    IMMDeviceEnumerator *pMMDeviceEnumerator;\r\n    // activate a device enumerator\r\n    hr = CoCreateInstance(\r\n        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, \r\n        __uuidof(IMMDeviceEnumerator),\r\n        (void**)&pMMDeviceEnumerator\r\n    );\r\n    if (FAILED(hr)) {\r\n        printf(\"CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\\n\", hr);\r\n        return hr;\r\n    }\r\n\r\n    // get the default render endpoint\r\n    hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, ppMMDevice);\r\n    pMMDeviceEnumerator->Release();\r\n    if (FAILED(hr)) {\r\n        printf(\"IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: hr = 0x%08x\\n\", hr); // we get here if no headphones plugged in\r\n        return hr;\r\n    }\r\n    return S_OK;\r\n}\r\n"
  },
  {
    "path": "source_code/acam/loopback-capture.cpp",
    "content": "#include \"stdafx.h\"\r\n\r\n#include <streams.h>\r\n#include <windows.h>\r\n#include <audioclient.h>\r\n#include <stdio.h>\r\n#include <avrt.h>\r\n#include \"common.h\"\r\n#include \"assert.h\"\r\n#include <memory.h>\r\n\r\n//HRESULT open_file(LPCWSTR szFileName, HMMIO *phFile);\r\n\r\n\r\nvoid outputStats();\r\nHRESULT start_silence_thread();\r\nHRESULT join_silence_thread();\r\nIAudioCaptureClient *pAudioCaptureClient;\r\nIAudioClient *pAudioClient;\r\nHANDLE hTask;\r\nbool bDiscontinuityDetected; // init'd eleswhere\r\nbool bVeryFirstPacket; // init'd elsewhere\r\nIMMDevice *m_pMMDevice;\r\nUINT32 nBlockAlign;\r\nUINT32 pnFrames;\r\n\r\nbool propagatingNormally;\r\n\r\nCCritSec csMyLock;  // shared critical section. Starts not locked...\r\n\r\nint shouldStop = true;\r\n\r\nBYTE pBufLocal[1024*1024]; // 1MB is quite awhile I think...\r\nlong pBufOriginalSize = 1024*1024;\r\n//long pBufLocalSize = 1024*1024; // used for buffer size negotiation method, use expectedmaxbuffersize instead\r\nlong pBufLocalCurrentEndLocation = 0;\r\n\r\nlong expectedMaxBufferSize = 1024*1024; // TODO make non-global\r\n\r\nHANDLE m_hThread;\r\n\r\nstatic DWORD WINAPI propagateBufferForever(LPVOID pv);\r\n\r\n\r\n#define EXIT_ON_ERROR(hres)  \\\r\n              if (FAILED(hres)) { return hres; }\r\n#define REFTIMES_PER_SEC  10000000\r\n\r\n\r\nconst CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);\r\nconst IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);\r\nconst IID IID_IAudioClient = __uuidof(IAudioClient);\r\nconst IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);\r\n\r\nvoid propagateWithRawCurrentFormat(WAVEFORMATEX *toThis, HRESULT *hrOut) {\r\n\tWAVEFORMATEX *pwfx;\r\n\tIMMDevice *pMMDevice;\r\n\tIAudioClient *pAudioClient;\r\n    HANDLE hTask;\r\n    DWORD nTaskIndex = 0;\r\n    hTask = AvSetMmThreadCharacteristics(L\"Capture\", &nTaskIndex);\r\n\r\n    HRESULT hr = get_default_device(&pMMDevice);\r\n    if (FAILED(hr)) {\r\n\t\t*hrOut = hr;\r\n\t\treturn;\r\n    }\r\n\t// activate an (the default, for us, since we want loopback) IAudioClient\r\n    hr = pMMDevice->Activate(\r\n        __uuidof(IAudioClient),\r\n        CLSCTX_ALL, NULL,\r\n        (void**)&pAudioClient\r\n    );\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IMMDevice::Activate(IAudioClient) failed: hr = 0x%08x\", hr);\r\n\t\t*hrOut = hr;\r\n\t\treturn;\r\n    }\r\n\r\n\thr = pAudioClient->GetMixFormat(&pwfx);\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::GetMixFormat failed: hr = 0x%08x\\n\", hr);\r\n        CoTaskMemFree(pwfx);\r\n        pAudioClient->Release();\r\n\t\t*hrOut = hr;\r\n\t\treturn;\r\n    }\r\n\tpAudioClient->Stop();\r\n    AvRevertMmThreadCharacteristics(hTask);\r\n    pAudioClient->Release();\r\n    pMMDevice->Release();\r\n\tmemcpy(toThis, pwfx, sizeof(WAVEFORMATEX));\r\n\tCoTaskMemFree(pwfx); \r\n\t*hrOut = S_OK;\r\n}\r\n\r\nint getHtzRate(HRESULT *hr) { // called earliest so return \"is it alive?\"\r\n\tWAVEFORMATEX format;\r\n\tpropagateWithRawCurrentFormat(&format, hr);\r\n\treturn format.nSamplesPerSec;\r\n}\r\n/*\r\nint getBitsPerSample() {\r\n\tWAVEFORMATEX format;\r\n\tpropagateWithRawCurrentFormat(&format);\r\n\treturn format.wBitsPerSample;\r\n}\r\n*/\r\nint getChannels() {\r\n\tWAVEFORMATEX format;\r\n    HRESULT hr;\r\n\tpropagateWithRawCurrentFormat(&format, &hr);\r\n\treturn format.nChannels;\r\n}\r\n\r\n// we only call this once...per hit of the play button :)\r\nHRESULT LoopbackCaptureSetup()\r\n{\r\n\tassert(shouldStop); // double start would be odd...\r\n\tshouldStop = false; // allow graphs to restart, if they so desire...\r\n\tpnFrames = 0;\r\n\tbool bInt16 = true; // makes it actually work, for some reason...my guess is it's a more common format\r\n\t\r\n    HRESULT hr;\r\n    hr = get_default_device(&m_pMMDevice); // so it can re-place our pointer...\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n\t// tell it to not overflow one buffer's worth <sigh> not sure if this is right or not, and thus we don't \"cache\" or \"buffer\" more than that much currently...\r\n\t// but a buffer size is a buffer size...hmm...as long as we keep it small though...\r\n\tassert(expectedMaxBufferSize <= pBufOriginalSize);\r\n    // activate an (the default, for us, since we want loopback) IAudioClient\r\n    hr = m_pMMDevice->Activate(\r\n        __uuidof(IAudioClient),\r\n        CLSCTX_ALL, NULL,\r\n        (void**)&pAudioClient\r\n    );\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IMMDevice::Activate(IAudioClient) failed: hr = 0x%08x\", hr);\r\n        return hr;\r\n    }\r\n    \r\n    // get the default device periodicity, why? I don't know...\r\n    REFERENCE_TIME hnsDefaultDevicePeriod;\r\n    hr = pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, NULL);\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::GetDevicePeriod failed: hr = 0x%08x\\n\", hr);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n\r\n    // get the default device format (incoming...)\r\n    WAVEFORMATEX *pwfx; // incoming wave...\r\n\t// apparently propogated by GetMixFormat...\r\n    hr = pAudioClient->GetMixFormat(&pwfx); // we free pwfx\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::GetMixFormat failed: hr = 0x%08x\\n\", hr);\r\n        CoTaskMemFree(pwfx);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n\r\n    if (true /*bInt16*/) {\r\n        // coerce int-XX wave format (like int-16 or int-32)\r\n        // can do this in-place since we're not changing the size of the format\r\n        // also, the engine will auto-convert from float to int for us\r\n        switch (pwfx->wFormatTag) {\r\n            case WAVE_FORMAT_IEEE_FLOAT:\r\n\t\t\t\tassert(false);// we never get here...I never have anyway...my guess is windows vista+ by default just uses WAVE_FORMAT_EXTENSIBLE\r\n                pwfx->wFormatTag = WAVE_FORMAT_PCM;\r\n                pwfx->wBitsPerSample = 16;\r\n                pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;\r\n                pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;\r\n                break;\r\n\r\n            case WAVE_FORMAT_EXTENSIBLE: // 65534\r\n                {\r\n                    // naked scope for case-local variable\r\n                    PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);\r\n                    if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat)) {\r\n\t\t\t\t\t\t// WE GET HERE!\r\n                        pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;\r\n\t\t\t\t\t\t// convert it to PCM, but let it keep as many bits of precision as it has initially...though it always seems to be 32\r\n\t\t\t\t\t\t// comment this out and set wBitsPerSample to  pwfex->wBitsPerSample = getBitsPerSample(); to get an arguably \"better\" quality 32 bit pcm\r\n\t\t\t\t\t\t// unfortunately flash media live encoder basically rejects 32 bit pcm, and it's not a huge gain sound quality-wise, so disabled for now.\r\n                        pwfx->wBitsPerSample = 16;\r\n\t\t\t\t\t\tpEx->Samples.wValidBitsPerSample = pwfx->wBitsPerSample;\r\n                        pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;\r\n                        pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;\r\n\t\t\t\t\t\t// see also setupPwfex method\r\n                    } else {\r\n                        ShowOutput(\"Don't know how to coerce mix format to int-16\\n\");\r\n                        CoTaskMemFree(pwfx);\r\n                        pAudioClient->Release();\r\n                        return E_UNEXPECTED;\r\n                    }\r\n                }\r\n                break;\r\n\r\n            default:\r\n                ShowOutput(\"Don't know how to coerce WAVEFORMATEX with wFormatTag = 0x%08x to int-16\\n\", pwfx->wFormatTag);\r\n                CoTaskMemFree(pwfx);\r\n                pAudioClient->Release();\r\n                return E_UNEXPECTED;\r\n        }\r\n    }\r\n\r\n    MMCKINFO ckRIFF = {0};\r\n    MMCKINFO ckData = {0};\r\n\r\n    nBlockAlign = pwfx->nBlockAlign;\r\n    \r\n\r\n// avoid stuttering on close when using loopback\r\n// http://social.msdn.microsoft.com/forums/en-US/windowspro-audiodevelopment/thread/c7ba0a04-46ce-43ff-ad15-ce8932c00171/ \r\n\t\r\n//IAudioClient *pAudioClient = NULL;\r\n//IAudioCaptureClient *pCaptureClient = NULL;\r\n\t\r\nIMMDeviceEnumerator *pEnumerator = NULL;\r\nIMMDevice *pDevice = NULL;\r\n\r\nIAudioRenderClient *pRenderClient = NULL;\r\nWAVEFORMATEXTENSIBLE *captureDataFormat = NULL;\r\nBYTE *captureData;\r\n\r\n    REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;\r\n\r\n    hr = CoCreateInstance(\r\n           CLSID_MMDeviceEnumerator, NULL,\r\n           CLSCTX_ALL, IID_IMMDeviceEnumerator,\r\n           (void**)&pEnumerator);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    hr = get_default_device(&pDevice);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    hr = pAudioClient->GetMixFormat((WAVEFORMATEX **)&captureDataFormat);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n\t\r\n    // Silence: initialise in sharedmode [this is the \"silence\" bug overwriter, so buffer doesn't matter as much...]\r\n    hr = pAudioClient->Initialize(\r\n                         AUDCLNT_SHAREMODE_SHARED,\r\n                         0,\r\n\t\t\t\t\t     REFTIMES_PER_SEC, // buffer size a full 1.0s, though prolly doesn't matter here.\r\n                         0,\r\n                         pwfx,\r\n                         NULL);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // get the frame count\r\n    UINT32  bufferFrameCount;\r\n    hr = pAudioClient->GetBufferSize(&bufferFrameCount);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // create a render client\r\n    hr = pAudioClient->GetService(IID_IAudioRenderClient, (void**)&pRenderClient);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // get the buffer\r\n    hr = pRenderClient->GetBuffer(bufferFrameCount, &captureData);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // release it\r\n    hr = pRenderClient->ReleaseBuffer(bufferFrameCount, AUDCLNT_BUFFERFLAGS_SILENT);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // release the audio client\r\n    pAudioClient->Release();\r\n    EXIT_ON_ERROR(hr)\r\n\r\n\r\n    // create a new IAudioClient\r\n    hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);\r\n    EXIT_ON_ERROR(hr)\r\n\r\n    // -============================ now the sniffing code initialization stuff, direct from mauritius... ===================================\r\n\r\n\t// call IAudioClient::Initialize\r\n    // note that AUDCLNT_STREAMFLAGS_LOOPBACK and AUDCLNT_STREAMFLAGS_EVENTCALLBACK\r\n    // do not work together...\r\n    // the \"data ready\" event never gets set\r\n    // so we're going to have to do this in a timer-driven loop...\r\n\r\n    hr = pAudioClient->Initialize(\r\n        AUDCLNT_SHAREMODE_SHARED,\r\n        AUDCLNT_STREAMFLAGS_LOOPBACK,\r\n        REFTIMES_PER_SEC, // buffer size a full 1.0s, seems ok VLC\r\n\t\t0, pwfx, 0\r\n    );\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::Initialize failed: hr = 0x%08x\\n\", hr);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    CoTaskMemFree(pwfx);\r\n\r\n    // activate an IAudioCaptureClient\r\n    hr = pAudioClient->GetService(\r\n        __uuidof(IAudioCaptureClient),\r\n        (void**)&pAudioCaptureClient\r\n    );\r\n\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::GetService(IAudioCaptureClient) failed: hr 0x%08x\\n\", hr);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    \r\n    // register with MMCSS\r\n    DWORD nTaskIndex = 0;\r\n\r\n    hTask = AvSetMmThreadCharacteristics(L\"Capture\", &nTaskIndex);\r\n    if (NULL == hTask) {\r\n        DWORD dwErr = GetLastError();\r\n        ShowOutput(\"AvSetMmThreadCharacteristics failed: last error = %u\\n\", dwErr);\r\n        pAudioCaptureClient->Release();\r\n        pAudioClient->Release();\r\n        return HRESULT_FROM_WIN32(dwErr);\r\n    }    \r\n\r\n    // call IAudioClient::Start\r\n    hr = pAudioClient->Start();\r\n    if (FAILED(hr)) {\r\n        ShowOutput(\"IAudioClient::Start failed: hr = 0x%08x\\n\", hr);\r\n        AvRevertMmThreadCharacteristics(hTask);\r\n        pAudioCaptureClient->Release();\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    \r\n\t// init some var's [XXXX using global vars doesn't work if I had 2 of these at the same time in the same process [?]]\r\n    bDiscontinuityDetected = true;\r\n\tbVeryFirstPacket = true;\r\n\r\n\t// start the forever grabbing thread...\r\n\tDWORD dwThreadID;\r\n    m_hThread = CreateThread(NULL,\r\n                            0,\r\n                            propagateBufferForever,\r\n                            0,\r\n                            0,\r\n                            &dwThreadID);\r\n    if(!m_hThread)\r\n    {\r\n        DWORD dwErr = GetLastError();\r\n        return HRESULT_FROM_WIN32(dwErr);\r\n    } else {\r\n\t\t// we...shouldn't need this...maybe?\r\n\t\t// seems to make no difference anyway, and probably won't hurt...\r\n\t\thr = SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);\r\n        if (FAILED(hr)) {\r\n\t\t  return hr;\r\n  \t    }\r\n\t}\r\n\thr = start_silence_thread();\r\n\treturn hr;\r\n} // end LoopbackCaptureSetup\r\n\r\n\r\nHRESULT propagateBufferOnce();\r\n\r\nextern CCritSec gSharedState;\r\n\r\nint totalSuccessFullyread = 0;\r\nint totalBlips = 0;\r\nint totalOverflows = 0;\r\n\r\nHRESULT propagateBufferOnce() {\r\n\tHRESULT hr = S_OK;\r\n\r\n    // grab next audio chunk...\r\n\tint gotAnyAtAll = FALSE;\r\n\tDWORD start_time = timeGetTime();\r\n    while (!shouldStop) {\r\n        UINT32 nNextPacketSize;\r\n        hr = pAudioCaptureClient->GetNextPacketSize(&nNextPacketSize); // get next packet, if one is ready...\r\n        if (FAILED(hr)) {\r\n            ShowOutput(\"IAudioCaptureClient::GetNextPacketSize failed after %u frames: hr = 0x%08x\\n\", pnFrames, hr);\r\n            /*pAudioClient->Stop(); // cleaned up in the teardown, don't do it twice -> segfault! [we get here if unplug headphones]\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();*/            \r\n            return hr;\r\n        }\r\n\r\n        if (0 == nNextPacketSize) {\r\n            // (CA) - this condition appears on Win8 when there is \"silence\" in the audio stream \r\n\t\t\t// (CA) - we don't appear to hit this condition in Win7 .. so I have eliminated the logic in here for right now...\r\n\r\n\t\t\t/*\r\n\t\t\t// no data yet, we're waiting, between incoming chunks of audio. [occurs even with silence on the line--it just means no new data yet]\r\n\t\t\tDWORD millis_to_fill = (DWORD) (1.0/SECOND_FRACTIONS_TO_GRAB*1000); // truncate is ok :) -- 1s\r\n\t\t\tassert(millis_to_fill > 1); // sanity\r\n\t\t\tDWORD current_time = timeGetTime();\r\n\t\t\tif((current_time - start_time > millis_to_fill)) {\r\n\t\t\t\t// I don't think we ever get to here anymore...thankfully, since it's mostly broken code probably, anyway\r\n\t\t\t\tif(!gotAnyAtAll) {\r\n\t\t\t\t  // We get here under high load...\r\n\t\t\t      // ignore for now, but sleep more\r\n\t\t\t      ShowOutput(\"detected high amount of time without receiving a packet from the capturer!\");\r\n\t\t\t\t  start_time = timeGetTime();\r\n\t\t\t\t  Sleep(0);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t  Sleep(1); // doesn't seem to hurt cpu--\"sleep x ms\"\r\n\t\t\t  continue;\r\n\t\t\t}\r\n\t\t\t*/\r\n\t\t\tSleep(1);\r\n\t\t\tcontinue;\r\n        } else {\r\n\t\t  gotAnyAtAll = TRUE;\r\n\t\t  totalSuccessFullyread++;\r\n\t\t}\r\n\t\t\r\n        // get the captured data\r\n        BYTE *pData;\r\n        UINT32 nNumFramesToRead;\r\n        DWORD dwFlags;\r\n\r\n\t\t// I guess it gives us...as much audio as possible to read...probably\r\n\r\n        hr = pAudioCaptureClient->GetBuffer(\r\n            &pData,\r\n            &nNumFramesToRead,\r\n            &dwFlags,\r\n            NULL,\r\n            NULL\r\n        ); // ACTUALLY GET THE BUFFER which I assume it reads in the format of the fella we passed in\r\n        \r\n        \r\n        if (FAILED(hr)) {\r\n            ShowOutput(\"IAudioCaptureClient::GetBuffer failed after %u frames: hr = 0x%08x\\n\", pnFrames, hr);\r\n            /*pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();*/            \r\n            return hr;            \r\n        }\r\n\r\n\t\t{\r\n  \t\t  CAutoLock cAutoLockShared(&gSharedState);  // for the booleans, we lock csMyLock later :| XXXX weird?\r\n\r\n\t\t\tif( dwFlags == 0 ) {\r\n\t\t\t  // the good case, got audio packet\r\n\t\t\t  // we'll let fillbuffer set bDiscontinuityDetected = false; since it uses it to know if the next packet should restart, etc.\r\n\t\t\t} else if (bDiscontinuityDetected && AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY == dwFlags) {\r\n\t\t\t\tShowOutput(\"Probably spurious glitch reported on first packet, or two discontinuity errors occurred before it read from the cached buffer\\n\");\r\n\t\t\t\t\r\n\t\t\t\tbDiscontinuityDetected = true; // won't hurt, even if it is a real first packet :)\r\n\t\t\t\t\r\n\t\t\t\t// XXXX it should probably clear the buffers if it ever gets discontinuity\r\n\t\t\t\t// or \"let\" it clear the buffers then send the new data on\r\n\t\t\t\t// as we have any left-over data that will be assigned a wrong timestamp\r\n\t\t\t\t// but it won't be too far wrong, compared to what it would otherwise be with always\r\n\t\t\t\t// assigning it the current graph timestamp, like we used to...\r\n\t\t\t} else if (AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY == dwFlags) {\r\n\t\t\t\t  ShowOutput(\"IAudioCaptureClient::discontinuity GetBuffer set flags to 0x%08x after %u frames\\n\", dwFlags, pnFrames);\r\n\t\t\t\t  // expected your CPU gets behind or what not. I guess.\r\n\t\t\t\t  /*pAudioClient->Stop();\r\n\t\t\t\t  AvRevertMmThreadCharacteristics(hTask);\r\n\t\t\t\t  pAudioCaptureClient->Release();\t\t  \r\n\t\t\t\t  pAudioClient->Release();            \r\n\t\t\t\t  return E_UNEXPECTED;*/\r\n\t\t\t\t  \r\n\t\t\t\t  bDiscontinuityDetected = true;\r\n\t\t\t} else if (AUDCLNT_BUFFERFLAGS_SILENT == dwFlags) {\r\n     \t\t  // ShowOutput(\"IAudioCaptureClient::silence (just) from GetBuffer after %u frames\\n\", pnFrames);\r\n\t\t\t  // expected if there's silence (i.e. nothing playing), since we now include the \"silence generator\" work-around...\r\n\t\t      // at least in windows 7, we get here...\r\n\t\t\t} else {\r\n\t\t\t  // probably silence + discontinuity\r\n     \t\t  ShowOutput(\"IAudioCaptureClient::unknown discontinuity GetBuffer set flags to 0x%08x after %u frames\\n\", dwFlags, pnFrames);\t\t\t  \r\n\t\t\t  bDiscontinuityDetected = true; // probably is some type of discontinuity :P\r\n\t\t\t}\r\n\r\n\t\t\tif(bDiscontinuityDetected)\r\n\t\t\t\ttotalBlips++;\r\n\r\n\t\t\tif (0 == nNumFramesToRead) {\r\n\t\t\t  // we should probably never get here, right?\r\n\t\t\t\t// my guess is that we don't, even in win8?\r\n\t\t\t\t// I mean, this is probably really messed up it told us it had some data to grab, we try to grab it, it returns us nothing?\r\n\t\t\t\t/*\r\n\t\t\t\tShowOutput(\"death failure: IAudioCaptureClient::GetBuffer said to read 0 frames after %u frames\\n\", pnFrames);\r\n\t\t\t\tpAudioClient->Stop();\r\n\t\t\t\tAvRevertMmThreadCharacteristics(hTask);\r\n\t\t\t\tpAudioCaptureClient->Release();\r\n\t\t\t\tpAudioClient->Release();\r\n\t\t\t\treturn E_UNEXPECTED;  \r\n\t\t\t\t*/\r\n\t\t\t}\r\n\r\n\t\t\tpnFrames += nNumFramesToRead; // increment total count...\t\t\r\n\r\n\t\t\t// lBytesToWrite typically 1792 bytes...\r\n\t\t\tLONG lBytesToWrite = nNumFramesToRead * nBlockAlign; // nBlockAlign is \"audio block size\" or frame size, for one audio segment...\r\n\t\t\t{\r\n\t\t\t  CAutoLock cObjectLock(&csMyLock);  // Lock the critical section, releases scope after block is over...\r\n\r\n\t\t\t  if(pBufLocalCurrentEndLocation > expectedMaxBufferSize) { \r\n\t\t\t\t// this happens during VLC pauses...\r\n\t\t\t\t// I have no idea what I'm doing here... this doesn't fix it, but helps a bit... TODO FINISH THIS\r\n\t\t\t\t// it seems like if you're just straight recording then you want this big...otherwise you want it like size 0 and non-threaded [pausing with graphedit, for example]... [?]\r\n\t\t\t\t// if you were recording skype, you'd want it non realtime...hmm...\r\n\t\t\t\t// it seems that if the cpu is loaded, we run into this if it's for the next packet...hmm...\r\n\t\t\t\t// so basically we don't accomodate realtime at all currently...hmmm...\r\n\t  \t\t\tShowOutput(\"overfilled buffer, cancelling/flushing.\"); //over flow overflow appears VLC just keeps reading though, when paused [?] but not graphedit...or does it?\r\n\t\t\t\tpBufLocalCurrentEndLocation = 0;\r\n\t\t\t\ttotalOverflows++;\r\n\t\t\t\tbDiscontinuityDetected = true;\r\n\t\t\t  }\r\n\r\n\t\t\t  for(INT i = 0; i < lBytesToWrite && pBufLocalCurrentEndLocation < expectedMaxBufferSize; i++) {\r\n\t\t\t\tpBufLocal[pBufLocalCurrentEndLocation++] = pData[i];\r\n\t\t\t  }\r\n\t\t\t}\r\n\t\t}\r\n        \r\n        hr = pAudioCaptureClient->ReleaseBuffer(nNumFramesToRead);\r\n        if (FAILED(hr)) {\r\n            ShowOutput(\"IAudioCaptureClient::ReleaseBuffer failed after %u frames: hr = 0x%08x\\n\", pnFrames, hr);\r\n            /*pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release(); */            \r\n            return hr;            \r\n        }\r\n        \r\n\t\treturn hr;\r\n    } // while !got anything && should continue loop\r\n\r\n\treturn S_OK; // stop was called...\r\n\r\n}\r\n\r\n// iSize is max size of the BYTE buffer...so maybe...we should just drop it if we have past that size? hmm...we're probably\r\nHRESULT LoopbackCaptureTakeFromBuffer(BYTE pBuf[], int iSize, WAVEFORMATEX* ifNotNullThenJustSetTypeOnly, LONG* totalBytesWrote)\r\n {\r\n\twhile(!shouldStop) { // allow this to exit, too, at shutdown, possibly a few times we kind of got stuck in here, waiting for more data, but it was shutdown so not receiving any more data :|\r\n       {\r\n        CAutoLock cObjectLock(&csMyLock);  // Lock the critical section, releases scope after block is done...\r\n\t\tif(pBufLocalCurrentEndLocation > 0) {\r\n\t\t  // fails lodo is that ok though? \r\n\t\t  // assert(pBufLocalCurrentEndLocation <= expectedMaxBufferSize);\r\n\t\t  int totalToWrite = MIN(pBufLocalCurrentEndLocation, expectedMaxBufferSize);\r\n\t\t  ASSERT(totalToWrite <= iSize); // just in case...just in case almost...\r\n\t\t  memcpy(pBuf, pBufLocal, totalToWrite);\r\n          *totalBytesWrote = totalToWrite;\r\n\t\t  pBufLocalCurrentEndLocation = 0;\r\n          return S_OK;\r\n\t\t} // else fall through to sleep outside the lock...\r\n\t  }\r\n\t  // sleep outside the lock ...\r\n\t  // using sleep doesn't seem to hurt the cpu\r\n\t  // and it seems to not get many \"discontinuity\" messages currently...\r\n      Sleep(1);\r\n\t  if (!propagatingNormally) {\r\n\t\t  return E_FAIL; // the capture has died, Jim!\r\n\t  }\r\n\t}\r\n\treturn E_FAIL; // we didn't fill anything...and are shutting down...\r\n}\r\n\r\nvoid LoopbackCaptureClear() {\r\n        CAutoLock cObjectLock(&csMyLock);  // Lock the critical section, releases scope after block is done...\r\n\t\tpBufLocalCurrentEndLocation = 0;\r\n\t\tbDiscontinuityDetected = 1; // it uses this for timestamping the next packet\r\n}\r\n\r\n// clean up\r\nvoid loopBackRelease() {\r\n\t// tell running collector thread to end...\r\n\tshouldStop = 1;\r\n\tWaitForSingleObject(m_hThread, INFINITE);\r\n    CloseHandle(m_hThread);\r\n    m_hThread = NULL;\r\n\tif (pAudioClient) {\r\n      m_pMMDevice->Release();\r\n\t  pAudioClient->Stop();\r\n\t  //pAudioClient->GetService();\r\n      pAudioCaptureClient->Release();\r\n      pAudioClient->Release();\r\n\r\n\t}\r\n    AvRevertMmThreadCharacteristics(hTask);\r\n\r\n\t// thread is done, we are exiting...\r\n\tpBufLocalCurrentEndLocation = 0;\r\n\toutputStats();\r\n\tjoin_silence_thread();\r\n}\r\n\r\n\r\nvoid outputStats() {\r\n\twchar_t output[250];\r\n\twsprintf(output, L\"v. %s total reads %d total discontinuity blips %d,  total overflows %d\", VIRTUAL_AUDIO_VERSION, totalSuccessFullyread , totalBlips - 1, totalOverflows);\r\n\tset_config_string_setting(L\"last_output\", output);\r\n}\r\n\r\n// called via reflection :)\r\nstatic DWORD WINAPI propagateBufferForever(LPVOID pv) {\r\n  propagatingNormally = true; // XXXX use events, the coolio way :|\r\n  while(!shouldStop) {\r\n    HRESULT hr = propagateBufferOnce();\r\n\tif(FAILED(hr)) {\r\n\t  propagatingNormally = false;\r\n\t  return hr; // exit thread\r\n\t}\r\n  }\r\n  return S_OK;\r\n}\r\n"
  },
  {
    "path": "source_code/acam/silence.h",
    "content": "#include \"common.h\"\nstruct PlaySilenceThreadFunctionArguments {\n    IMMDevice *pMMDevice;\n    HANDLE hStartedEvent;\n    HANDLE hStopEvent;\n    HRESULT hr;\n};"
  },
  {
    "path": "source_code/acam/silence_background_thread.cpp",
    "content": "// silence.cpp from msdn blog\n#include \"stdafx.h\"\n#include <windows.h>\n#include <mmdeviceapi.h>\n#include <audioclient.h>\n#include <stdio.h>\n#include <avrt.h>\n\n#include \"silence.h\"\n\n// started in its own thread\nDWORD WINAPI PlaySilenceThreadFunction(LPVOID pContext) {\n    PlaySilenceThreadFunctionArguments *pArgs =\n        (PlaySilenceThreadFunctionArguments*)pContext;\n\n    IMMDevice *pMMDevice = pArgs->pMMDevice;\n    HRESULT &hr = pArgs->hr;\n\n    // CoInitialize (probably don't even need this...)\n    hr = CoInitialize(NULL);\n    if (FAILED(hr)) {\n        printf(\"CoInitialize failed: hr = 0x%08x\\n\", hr);\n        return 0;\n    }\n\n    // activate an IAudioClient\n    IAudioClient *pAudioClient;\n    hr = pMMDevice->Activate(\n        __uuidof(IAudioClient),\n        CLSCTX_ALL, NULL,\n        (void**)&pAudioClient\n    );\n    if (FAILED(hr)) {\n        printf(\"IMMDevice::Activate(IAudioClient) failed: hr = 0x%08x\", hr);\n        //CoUninitialize();\n        return 0;\n    }\n\n    // get the mix format\n    WAVEFORMATEX *pwfx;\n    hr = pAudioClient->GetMixFormat(&pwfx);\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::GetMixFormat failed: hr = 0x%08x\\n\", hr);\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // initialize the audio client\n    hr = pAudioClient->Initialize(\n        AUDCLNT_SHAREMODE_SHARED,\n        AUDCLNT_STREAMFLAGS_EVENTCALLBACK,\n        0, 0, pwfx, NULL\n    );\n    CoTaskMemFree(pwfx);\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::Initialize failed: hr 0x%08x\\n\", hr);\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // get the buffer size\n    UINT32 nFramesInBuffer;\n    hr = pAudioClient->GetBufferSize(&nFramesInBuffer);\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::GetBufferSize failed: hr 0x%08x\\n\", hr);\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // get an IAudioRenderClient\n    IAudioRenderClient *pAudioRenderClient;\n    hr = pAudioClient->GetService(\n        __uuidof(IAudioRenderClient),\n        (void**)&pAudioRenderClient\n    );\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::GetService(IAudioRenderClient) failed: hr 0x%08x\\n\", hr);\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // create a \"feed me\" event\n    HANDLE hFeedMe;\n    hFeedMe = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (NULL == hFeedMe) {\n        DWORD dwErr = GetLastError();\n        hr = HRESULT_FROM_WIN32(dwErr);\n        printf(\"CreateEvent failed: last error is %u\\n\", dwErr);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // set it as the event handle\n    hr = pAudioClient->SetEventHandle(hFeedMe);\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::SetEventHandle failed: hr = 0x%08x\\n\", hr);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // pre-fill a single buffer of silence\n    BYTE *pData;\n    hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);\n    if (FAILED(hr)) {\n        printf(\"IAudioRenderClient::GetBuffer failed on pre-fill: hr = 0x%08x\\n\", hr);\n        pAudioClient->Stop();\n        printf(\"TODO: unregister with MMCSS\\n\");\n        CloseHandle(hFeedMe);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n\n    // release the buffer with the silence flag\n    hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, AUDCLNT_BUFFERFLAGS_SILENT);\n    if (FAILED(hr)) {\n        printf(\"IAudioRenderClient::ReleaseBuffer failed on pre-fill: hr = 0x%08x\\n\", hr);\n        pAudioClient->Stop();\n        printf(\"TODO: unregister with MMCSS\\n\");\n        CloseHandle(hFeedMe);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }        \n\n    // register with MMCSS\n    DWORD nTaskIndex = 0;\n    HANDLE hTask = AvSetMmThreadCharacteristics(L\"Playback\", &nTaskIndex);\n    if (NULL == hTask) {\n        DWORD dwErr = GetLastError();\n        hr = HRESULT_FROM_WIN32(dwErr);\n        printf(\"AvSetMmThreadCharacteristics failed: last error = %u\\n\", dwErr);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }    \n\n    // call Start\n    hr = pAudioClient->Start();\n    if (FAILED(hr)) {\n        printf(\"IAudioClient::Start failed: hr = 0x%08x\\n\", hr);\n        printf(\"TODO: unregister with MMCSS\\n\");\n        AvRevertMmThreadCharacteristics(hTask);\n        pAudioRenderClient->Release();\n        pAudioClient->Release();\n        //CoUninitialize();\n        return 0;\n    }\n    SetEvent(pArgs->hStartedEvent);\n\n    HANDLE waitArray[2] = { pArgs->hStopEvent, hFeedMe };\n    DWORD dwWaitResult;\n\n    bool bDone = false;\n    for (UINT32 nPasses = 0; !bDone; nPasses++) {\n        dwWaitResult = WaitForMultipleObjects(\n            ARRAYSIZE(waitArray), waitArray,\n            FALSE, INFINITE\n        );\n\n        if (WAIT_OBJECT_0 == dwWaitResult) {\n            printf(\"Received stop event after %u passes\\n\", nPasses);\n            bDone = true;\n            continue; // exits loop\n        }\n\n        if (WAIT_OBJECT_0 + 1 != dwWaitResult) {\n            hr = E_UNEXPECTED;\n            printf(\"Unexpected WaitForMultipleObjects return value %u on pass %u\\n\", dwWaitResult, nPasses);\n            pAudioClient->Stop();\n            AvRevertMmThreadCharacteristics(hTask);\n            CloseHandle(hFeedMe);\n            pAudioRenderClient->Release();\n            pAudioClient->Release();\n            //CoUninitialize();\n            return 0;\n        }\n\n        // got \"feed me\" event - see how much padding there is\n        //\n        // padding is how much of the buffer is currently in use\n        //\n        // note in particular that event-driven (pull-mode) render should not\n        // call GetCurrentPadding multiple times\n        // in a single processing pass\n        // this is in stark contrast to timer-driven (push-mode) render\n        UINT32 nFramesOfPadding;\n        hr = pAudioClient->GetCurrentPadding(&nFramesOfPadding);\n        if (FAILED(hr)) {\n            ShowOutput(\"IAudioClient::GetCurrentPadding failed on pass %u: hr = 0x%08x\\n\", nPasses, hr);\n            pAudioClient->Stop();\n            AvRevertMmThreadCharacteristics(hTask);\n            CloseHandle(hFeedMe);\n            pAudioRenderClient->Release();\n            pAudioClient->Release();\n            //CoUninitialize();\n            return 0;\n        }\n\n        if (nFramesOfPadding == nFramesInBuffer) {\n            hr = E_UNEXPECTED;\n            ShowOutput(\"Got \\\"feed me\\\" event but IAudioClient::GetCurrentPadding reports buffer is full - glitch?\\n\"); \n\t\t\t// he said he ran into ths at least once?\n            /*pAudioClient->Stop();\n            AvRevertMmThreadCharacteristics(hTask);\n            CloseHandle(hFeedMe);\n            pAudioRenderClient->Release();\n            pAudioClient->Release();\n            //CoUninitialize();\n            return 0; */\n        }\n    \n        hr = pAudioRenderClient->GetBuffer(nFramesInBuffer - nFramesOfPadding, &pData);\n        if (FAILED(hr)) {\n            printf(\"IAudioRenderClient::GetBuffer failed on pass %u: hr = 0x%08x - glitch?\\n\", nPasses, hr);\n            pAudioClient->Stop();\n            AvRevertMmThreadCharacteristics(hTask);\n            CloseHandle(hFeedMe);\n            pAudioRenderClient->Release();\n            pAudioClient->Release();\n            //CoUninitialize();\n            return 0;\n        }\n\n        // *** AT THIS POINT ***\n        // If you wanted to render something besides silence,\n        // you would fill the buffer pData\n        // with (nFramesInBuffer - nFramesOfPadding) worth of audio data\n        // this should be in the same wave format\n        // that the stream was initialized with\n        //\n        // In particular, if you didn't want to use the mix format,\n        // you would need to either ask for a different format in IAudioClient::Initialize\n        // or do a format conversion\n        //\n        // If you do, then change the AUDCLNT_BUFFERFLAGS_SILENT flags value below to 0\n\n        // release the buffer with the silence flag\n        hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer - nFramesOfPadding, AUDCLNT_BUFFERFLAGS_SILENT);\n        if (FAILED(hr)) {\n            printf(\"IAudioRenderClient::ReleaseBuffer failed on pass %u: hr = 0x%08x - glitch?\\n\", nPasses, hr);\n            pAudioClient->Stop();\n            AvRevertMmThreadCharacteristics(hTask);\n            CloseHandle(hFeedMe);\n            pAudioRenderClient->Release();\n            pAudioClient->Release();\n            //CoUninitialize();\n            return 0;\n        }        \n    } // for each pass\n\n    pAudioClient->Stop();\n    AvRevertMmThreadCharacteristics(hTask);\n    CloseHandle(hFeedMe);\n    pAudioRenderClient->Release();\n    pAudioClient->Release();\n    //CoUninitialize();\n    return 0;\n}\n"
  },
  {
    "path": "source_code/acam/silence_control.cpp",
    "content": "#include \"stdafx.h\"\n#include <stdio.h>\n#include \"silence.h\"\n\nIMMDevice *m_pMMSilenceDevice;\n\nHANDLE hStartedEvent;\nHANDLE hStopEvent;\nHANDLE hThread;\nDWORD WINAPI PlaySilenceThreadFunction(LPVOID pContext);\nPlaySilenceThreadFunctionArguments threadArgs;\n\nHRESULT start_silence_thread() {\n    // create a \"silence has started playing\" event\n    hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (NULL == hStartedEvent) {\n        printf(\"CreateEvent failed: last error is %u\\n\", GetLastError());\n        return __LINE__;\n    }\n\n    // create a \"stop playing silence now\" event\n    hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n    if (NULL == hStopEvent) {\n        printf(\"CreateEvent failed: last error is %u\\n\", GetLastError());\n        CloseHandle(hStartedEvent);\n        return __LINE__;\n    }\n    HRESULT hr = get_default_device(&m_pMMSilenceDevice);\n\t if (FAILED(hr)) {\n        printf(\"get_def_device failed: hr = 0x%08x\\n\", hr);\n        return __LINE__;\n    }\n    // create arguments for silence-playing thread\n\n    threadArgs.hr = E_UNEXPECTED; // thread will overwrite this\n    threadArgs.hStartedEvent = hStartedEvent;\n    threadArgs.hStopEvent = hStopEvent;\n    threadArgs.pMMDevice = m_pMMSilenceDevice;\n\n    hThread = CreateThread(\n        NULL, 0,\n        PlaySilenceThreadFunction, &threadArgs,\n        0, NULL\n    );\n    if (NULL == hThread) {\n        printf(\"CreateThread failed: last error is %u\\n\", GetLastError());\n        CloseHandle(hStopEvent);\n        CloseHandle(hStartedEvent);\n        return __LINE__;\n    }\n\n    // wait for either silence to start or the thread to end/abort unexpectedly :|\n    HANDLE waitArray[2] = { hStartedEvent, hThread };\n    DWORD dwWaitResult;\n    dwWaitResult = WaitForMultipleObjects(\n        ARRAYSIZE(waitArray), waitArray,\n        FALSE, INFINITE\n    );\n\n    if (WAIT_OBJECT_0 + 1 == dwWaitResult) {\n        printf(\"Thread aborted before starting to play silence: hr = 0x%08x\\n\", threadArgs.hr);\n        CloseHandle(hStartedEvent);\n        CloseHandle(hThread);\n        CloseHandle(hStopEvent);\n        return __LINE__;\n    }\n\n    if (WAIT_OBJECT_0 != dwWaitResult) {\n        printf(\"Unexpected WaitForMultipleObjects return value %u: last error is %u\\n\", dwWaitResult, GetLastError());\n        CloseHandle(hStartedEvent);\n        CloseHandle(hThread);\n        CloseHandle(hStopEvent);\n        return __LINE__;\n    }\n\n    CloseHandle(hStartedEvent);\n\treturn S_OK;\n}\n\nHRESULT join_silence_thread() {\n\tSetEvent(hStopEvent);\n\tWaitForSingleObject(hThread, INFINITE);\n\n\t// wait for the thread to terminate\n\tHANDLE rhHandles[1] = { hThread };\n\n\tDWORD exitCode;\n\tif (!GetExitCodeThread(hThread, &exitCode)) {\n\t\tprintf(\"GetExitCodeThread failed: last error is %u\\n\", GetLastError());\n\t\tCloseHandle(hThread);\n\t\tCloseHandle(hStopEvent);\n\t\treturn __LINE__;\n\t}\n\n\tif (0 != exitCode) {\n\t\tprintf(\"Silence thread exit code is %u; expected 0\\n\", exitCode);\n\t\tCloseHandle(hThread);\n\t\tCloseHandle(hStopEvent);\n\t\treturn __LINE__;\n\t}\n\n\t/*    if (S_OK != threadArgs.hr) { // didn't care enuf :|\n\tprintf(\"Thread HRESULT is 0x%08x\\n\", threadArgs.hr);\n\tCloseHandle(hThread);\n\tCloseHandle(hStopEvent);\n\treturn __LINE__;\n\t} */\n\n\tCloseHandle(hThread);\n\tCloseHandle(hStopEvent);\n\tShowOutput(\"silence thread done success!\");\n\treturn S_OK;\n}\n"
  },
  {
    "path": "source_code/acam/stdafx.cpp",
    "content": "// stdafx.cpp : source file that includes just the standard includes\r\n// acam.pch will be the pre-compiled header\r\n// stdafx.obj will contain the pre-compiled type information\r\n\r\n#include \"stdafx.h\"\r\n\r\n// TODO: reference any additional headers you need in STDAFX.H\r\n// and not in this file\r\n"
  },
  {
    "path": "source_code/acam/stdafx.h",
    "content": "// stdafx.h : include file for standard system include files,\r\n// or project specific include files that are used frequently, but\r\n// are changed infrequently\r\n//\r\n\r\n#pragma once\r\n\r\n#include \"targetver.h\"\r\n\r\n#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers\r\n// Windows Header Files:\r\n#include <windows.h>\r\n"
  },
  {
    "path": "source_code/acam/targetver.h",
    "content": "#pragma once\r\n\r\n// Including SDKDDKVer.h defines the highest available Windows platform.\r\n\r\n// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\r\n// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\r\n\r\n#include <SDKDDKVer.h>\r\n"
  },
  {
    "path": "source_code/acam/utilities.cpp",
    "content": "#include \"stdafx.h\"\r\n#include <stdio.h>\r\n\r\n/* unused ...\r\nvoid logToFile(char *log_this) {\r\n    FILE *f;\r\n\tf = fopen(\"g:\\\\yo2\", \"a\");\r\n\tfprintf(f, log_this);\r\n\tfclose(f);\r\n} */\r\n\r\nvoid ShowOutput(const char *str, ...)\r\n{\r\n#ifdef _DEBUG  // avoid in release mode\r\n  char buf[2048];\r\n  va_list ptr;\r\n  va_start(ptr,str);\r\n  vsprintf_s(buf,str,ptr);\r\n  OutputDebugStringA(buf);\r\n  OutputDebugStringA(\"\\n\");\r\n  //printf(\"%s\\n\", buf);\r\n  //logToFile(buf);\r\n  va_end(ptr);\r\n#endif\r\n}\r\n\r\nHRESULT set_config_string_setting(LPCTSTR szValueName, wchar_t *szToThis) {\r\n\r\n   HKEY hKey = NULL;\r\n   LONG i;\r\n\r\n    DWORD dwDisp = 0;\r\n    LPDWORD lpdwDisp = &dwDisp;\r\n\r\n    i = RegCreateKeyEx(HKEY_CURRENT_USER,\r\n       L\"SOFTWARE\\\\virtual_audio_capture\", 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_32KEY, NULL, &hKey, lpdwDisp); // might fail in flash player...?\r\n\r\n    if (i == ERROR_SUCCESS)\r\n    {\r\n\t\t// bad for XP  ... = RegSetKeyValueA(hKey, NULL, szValueName, REG_SZ, ...\r\n        i = RegSetValueEx(hKey, szValueName, 0, REG_SZ, (LPBYTE) szToThis, wcslen(szToThis)*2+1);\r\n\r\n    } else {\r\n       // failed to create key...\r\n\t}\r\n\r\n\tif(hKey)\r\n\t  RegCloseKey(hKey);\r\n\treturn i;\r\n\r\n}\r\n"
  },
  {
    "path": "source_code/acam_is_where_all_the_code_is",
    "content": ""
  },
  {
    "path": "source_code/startup_debug_options",
    "content": "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\graphedt\r\nc:\\dev\\ruby\\virtual-audio-output-sniffer\\yo.grf\r\n\r\nC:\\installs\\graphstudionext.exe\r\n\r\nc:\\dev\\virtual-audio-capture-grabber-device\\source_code\\yo2.grf\r\n\r\nC:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe\r\ndshow://  :dshow-vdev=none :dshow-adev=\"virtual-audio-capturer\"  :dshow-caching=100\r\n\r\nC:\\Program Files (x86)\\Adobe\\Flash Media Live Encoder 3.2\\FlashMediaLiveEncoder.exe\r\n\r\nC:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe \r\ndshow://  :dshow-vdev=none :dshow-adev=\"virtual-audio-capturer\"  :dshow-caching=50\r\nC:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\graphedt.exe\r\n\r\nc:\\dev\\ruby\\sensible-cinema\\vendor\\cache\\ffmpeg\\ffmpeg.exe\r\n-y -f dshow -i audio=virtual-audio-capturer -t 5 yo.wav\r\n\r\nc:\\vids\\ffmpeg.exe\r\n-f dshow  -i audio=virtual-audio-capturer -y yo.mp4"
  },
  {
    "path": "source_code/synth_deprecated/Synth.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectGuid>{BF20BC76-A330-4857-830B-80C85660478B}</ProjectGuid>\r\n    <RootNamespace>Synth</RootNamespace>\r\n    <Keyword>Win32Proj</Keyword>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(Platform)\\$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(Platform)\\$(Configuration)\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(Platform)\\$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(Platform)\\$(Configuration)\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\r\n    <IncludePath Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">G:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Samples\\multimedia\\directshow\\baseclasses;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\\include;</IncludePath>\r\n    <LibraryPath Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(VCInstallDir)lib;$(VCInstallDir)atlmfc\\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\\lib;G:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Samples\\multimedia\\directshow\\baseclasses\\Debug</LibraryPath>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <AdditionalIncludeDirectories>..\\..\\BaseClasses\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <MinimalRebuild>true</MinimalRebuild>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r\n      <CallingConvention>StdCall</CallingConvention>\r\n    </ClCompile>\r\n    <Link>\r\n      <AdditionalDependencies>strmbasd.lib;winmm.lib;msvcrtd.lib;Msacm32.lib;comctl32.lib;%(AdditionalDependencies);Avrt.lib</AdditionalDependencies>\r\n      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>\r\n      <ModuleDefinitionFile>synth.def</ModuleDefinitionFile>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Windows</SubSystem>\r\n      <TargetMachine>MachineX86</TargetMachine>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <AdditionalIncludeDirectories>..\\..\\BaseClasses\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <CallingConvention>StdCall</CallingConvention>\r\n    </ClCompile>\r\n    <Link>\r\n      <AdditionalDependencies>..\\..\\BaseClasses\\Release\\strmbase.lib;winmm.lib;msvcrt.lib;Msacm32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>\r\n      <ModuleDefinitionFile>synth.def</ModuleDefinitionFile>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Windows</SubSystem>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <TargetMachine>MachineX86</TargetMachine>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <Midl>\r\n      <TargetEnvironment>X64</TargetEnvironment>\r\n    </Midl>\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <AdditionalIncludeDirectories>..\\..\\BaseClasses\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <MinimalRebuild>true</MinimalRebuild>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <CallingConvention>StdCall</CallingConvention>\r\n    </ClCompile>\r\n    <Link>\r\n      <AdditionalDependencies>strmbasd.lib;winmm.lib;msvcrtd.lib;Msacm32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalLibraryDirectories>..\\..\\BaseClasses\\x64\\Debug\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\n      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>\r\n      <ModuleDefinitionFile>synth.def</ModuleDefinitionFile>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Windows</SubSystem>\r\n      <TargetMachine>MachineX64</TargetMachine>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <Midl>\r\n      <TargetEnvironment>X64</TargetEnvironment>\r\n    </Midl>\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <AdditionalIncludeDirectories>..\\..\\BaseClasses\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n      <CallingConvention>StdCall</CallingConvention>\r\n    </ClCompile>\r\n    <Link>\r\n      <AdditionalDependencies>strmbase.lib;winmm.lib;msvcrt.lib;Msacm32.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalLibraryDirectories>..\\..\\BaseClasses\\x64\\Release\\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r\n      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>\r\n      <ModuleDefinitionFile>synth.def</ModuleDefinitionFile>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Windows</SubSystem>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <TargetMachine>MachineX64</TargetMachine>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dynsrc.cpp\" />\r\n    <ClCompile Include=\"loopback-capture-helpers.cpp\" />\r\n    <ClCompile Include=\"loopback-capture.cpp\" />\r\n    <ClCompile Include=\"synth.cpp\" />\r\n    <ClCompile Include=\"synthprp.cpp\" />\r\n    <ClCompile Include=\"useless_synth.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"synth.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"dynsrc.h\" />\r\n    <ClInclude Include=\"isynth.h\" />\r\n    <ClInclude Include=\"resource.h\" />\r\n    <ClInclude Include=\"synth.h\" />\r\n    <ClInclude Include=\"synthprp.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"synth.rc\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "source_code/synth_deprecated/Synth.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dynsrc.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"synth.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"synthprp.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"useless_synth.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"loopback-capture.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"loopback-capture-helpers.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"synth.def\">\r\n      <Filter>Source Files</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"dynsrc.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"isynth.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"resource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"synth.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"synthprp.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"synth.rc\">\r\n      <Filter>Resource Files</Filter>\r\n    </ResourceCompile>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "source_code/synth_deprecated/Synth.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LocalDebuggerCommand>c:\\Program Files\\VideoLAN\\vlc\\vlc.exe</LocalDebuggerCommand>\r\n    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r\n  </PropertyGroup>\r\n</Project>"
  },
  {
    "path": "source_code/synth_deprecated/dynsrc.cpp",
    "content": "//------------------------------------------------------------------------------\r\n// File: DynSrc.cpp\r\n//\r\n// Desc: DirectShow sample code - implements CDynamicSource, which is a\r\n//       Quartz source filter.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\n// I think this is not what I'm looking for, move along now...\r\n\r\n// Locking Strategy.\r\n//\r\n// Hold the filter critical section (m_pFilter->pStateLock()) to serialise\r\n// access to functions. Note that, in general, this lock may be held\r\n// by a function when the worker thread may want to hold it. Therefore\r\n// if you wish to access shared state from the worker thread you will\r\n// need to add another critical section object. The execption is during\r\n// the threads processing loop, when it is safe to get the filter critical\r\n// section from within FillBuffer().\r\n\r\n// I think we don't have to worry about this one...\r\n\r\n\r\n#include <windows.h>\r\n#include <streams.h>\r\n\r\n#include \"DynSrc.h\"\r\n\r\n\r\nCDynamicSource::CDynamicSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr)\r\n    : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),\r\n      m_iPins(0),\r\n      m_paStreams(NULL),\r\n      m_evFilterStoppingEvent(TRUE)\r\n{\r\n    ASSERT(phr);\r\n    \r\n    // Make sure the event was successfully created.\r\n    if( NULL == (HANDLE)m_evFilterStoppingEvent ) {\r\n        if (phr)\r\n            *phr = E_FAIL;\r\n    }\r\n}\r\n\r\n\r\n#ifdef UNICODE\r\nCDynamicSource::CDynamicSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr)\r\n    : CBaseFilter(pName, lpunk, &m_cStateLock, clsid),\r\n      m_iPins(0),\r\n      m_paStreams(NULL),\r\n      m_evFilterStoppingEvent(TRUE)\r\n{\r\n    ASSERT(phr);\r\n\r\n    // Make sure the event was successfully created.\r\n    if( NULL == (HANDLE)m_evFilterStoppingEvent ) {\r\n        if (phr)\r\n            *phr = E_FAIL;\r\n    }\r\n}\r\n#endif\r\n\r\n\r\n//\r\n// CDynamicSource::Destructor\r\n//\r\nCDynamicSource::~CDynamicSource()\r\n{\r\n    /*  Free our pins and pin array */\r\n    while (m_iPins != 0) \r\n    {\r\n        // deleting the pins causes them to be removed from the array...\r\n        delete m_paStreams[m_iPins - 1];\r\n    }\r\n\r\n    ASSERT(m_paStreams == NULL);\r\n}\r\n\r\n\r\n//\r\n//  Add a new pin\r\n//\r\nHRESULT CDynamicSource::AddPin(CDynamicSourceStream *pStream)\r\n{\r\n    // This function holds the filter state lock because\r\n    // it changes the number of pins.  The number of pins\r\n    // cannot be change while another thread is calling\r\n    // IMediaFilter::Run(), IMediaFilter::Stop(), \r\n    // IMediaFilter::Pause() or IBaseFilter::FindPin().\r\n    CAutoLock lock(&m_cStateLock);\r\n\r\n    // This function holds the pin state lock because it\r\n    // uses m_iPins and m_paStreams.\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n    /*  Allocate space for this pin and the old ones */\r\n    CDynamicSourceStream **paStreams = new CDynamicSourceStream *[m_iPins + 1];\r\n    if (paStreams == NULL)\r\n        return E_OUTOFMEMORY;\r\n\r\n    if (m_paStreams != NULL) \r\n    {\r\n        CopyMemory((PVOID)paStreams, (PVOID)m_paStreams,\r\n                   m_iPins * sizeof(m_paStreams[0]));\r\n\r\n        paStreams[m_iPins] = pStream;\r\n        delete [] m_paStreams;\r\n    }\r\n\r\n    m_paStreams = paStreams;\r\n    m_paStreams[m_iPins] = pStream;\r\n    m_iPins++;\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n//\r\n//  Remove a pin - pStream is NOT deleted\r\n//\r\nHRESULT CDynamicSource::RemovePin(CDynamicSourceStream *pStream)\r\n{\r\n    // This function holds the filter state lock because\r\n    // it changes the number of pins.  The number of pins\r\n    // cannot be change while another thread is calling\r\n    // IMediaFilter::Run(), IMediaFilter::Stop(), \r\n    // IMediaFilter::Pause() or IBaseFilter::FindPin().\r\n    CAutoLock lock(&m_cStateLock);    \r\n\r\n    // This function holds the pin state lock because it\r\n    // uses m_iPins and m_paStreams.\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n    for(int i = 0; i < m_iPins; i++)\r\n    {\r\n        if(m_paStreams[i] == pStream)\r\n        {\r\n            if(m_iPins == 1)\r\n            {\r\n                delete [] m_paStreams;\r\n                m_paStreams = NULL;\r\n            }\r\n            else\r\n            {\r\n                /*  no need to reallocate */\r\n                while(++i < m_iPins)\r\n                    m_paStreams[i - 1] = m_paStreams[i];\r\n            }\r\n\r\n            m_iPins--;\r\n            return S_OK;\r\n        }\r\n    }\r\n\r\n    return S_FALSE;\r\n}\r\n\r\n\r\n//\r\n// FindPin\r\n//\r\n// Set *ppPin to the IPin* that has the id Id.\r\n// or to NULL if the Id cannot be matched.\r\nSTDMETHODIMP CDynamicSource::FindPin(LPCWSTR Id, IPin **ppPin)\r\n{\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n    CheckPointer(ppPin,E_POINTER);\r\n    ValidateReadWritePtr(ppPin,sizeof(IPin *));\r\n\r\n    // The -1 undoes the +1 in QueryId and ensures that totally invalid\r\n    // strings (for which WstrToInt delivers 0) give a deliver a NULL pin.\r\n    int i = WstrToInt(Id) -1;\r\n\r\n    *ppPin = GetPin(i);\r\n    if (*ppPin!=NULL)\r\n    {\r\n        (*ppPin)->AddRef();\r\n        return NOERROR;\r\n    }\r\n\r\n    return VFW_E_NOT_FOUND;\r\n}\r\n\r\n\r\n//\r\n// FindPinNumber\r\n//\r\n// return the number of the pin with this IPin* or -1 if none\r\nint CDynamicSource::FindPinNumber(IPin *iPin) \r\n{\r\n\r\n    // This function holds the pin state lock because it\r\n    // uses m_iPins and m_paStreams.\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n    for (int i=0; i<m_iPins; ++i) \r\n    {\r\n        if ((IPin *)(m_paStreams[i]) == iPin) \r\n        {\r\n            return i;\r\n        }\r\n    }\r\n\r\n    return -1;\r\n}\r\n\r\n\r\n//\r\n// GetPinCount\r\n//\r\n// Returns the number of pins this filter has\r\nint CDynamicSource::GetPinCount(void) \r\n{\r\n\r\n    // This function holds the pin state lock because it\r\n    // uses m_iPins.\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n    return m_iPins;\r\n}\r\n\r\n\r\n//\r\n// GetPin\r\n//\r\n// Return a non-addref'd pointer to pin n\r\n// needed by CBaseFilter\r\nCBasePin *CDynamicSource::GetPin(int n)\r\n{\r\n    // This function holds the pin state lock because it\r\n    // uses m_iPins and m_paStreams.\r\n    CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n    // n must be in the range 0..m_iPins-1\r\n    // if m_iPins>n  && n>=0 it follows that m_iPins>0\r\n    // which is what used to be checked (i.e. checking that we have a pin)\r\n    if((n >= 0) && (n < m_iPins))\r\n    {\r\n        ASSERT(m_paStreams[n]);\r\n        return m_paStreams[n];\r\n    }\r\n\r\n    return NULL;\r\n}\r\n\r\n\r\nSTDMETHODIMP CDynamicSource::Stop(void)\r\n{\r\n    m_evFilterStoppingEvent.Set();\r\n\r\n    HRESULT hr = CBaseFilter::Stop();\r\n\r\n    // The following code ensures that a pins thread will be destroyed even \r\n    // if the pin is disconnected when CBaseFilter::Stop() is called.\r\n    int nCurrentPin;\r\n    CDynamicSourceStream* pOutputPin;\r\n    {\r\n        // This code holds the pin state lock because it\r\n        // does not want the number of pins to change \r\n        // while it executes.\r\n        CAutoLock alPinStateLock(&m_csPinStateLock);\r\n\r\n        for(nCurrentPin = 0; nCurrentPin < GetPinCount(); nCurrentPin++)\r\n        {\r\n            pOutputPin = (CDynamicSourceStream*)GetPin(nCurrentPin);\r\n            if(pOutputPin->ThreadExists())\r\n            {\r\n                pOutputPin->DestroySourceThread();\r\n            }\r\n        }\r\n    }\r\n\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\nSTDMETHODIMP CDynamicSource::Pause(void)\r\n{\r\n    m_evFilterStoppingEvent.Reset();\r\n\r\n    return CBaseFilter::Pause();\r\n}\r\n\r\n\r\nSTDMETHODIMP CDynamicSource::JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName)\r\n{\r\n    CAutoLock lock(&m_cStateLock);\r\n\r\n    HRESULT hr;\r\n    int nCurrentPin;\r\n    CDynamicSourceStream* pOutputPin;\r\n\r\n    // The filter is joining the filter graph.\r\n    if(NULL != pGraph)\r\n    {\r\n        IGraphConfig* pGraphConfig = NULL;\r\n\r\n        hr = pGraph->QueryInterface(IID_IGraphConfig, (void**)&pGraphConfig);\r\n        if(FAILED(hr))\r\n        {\r\n            return hr;\r\n        }\r\n\r\n        hr = CBaseFilter::JoinFilterGraph(pGraph, pName);\r\n        if(FAILED(hr))\r\n        {\r\n            pGraphConfig->Release();\r\n            return hr;\r\n        }\r\n\r\n        for(nCurrentPin = 0; nCurrentPin < GetPinCount(); nCurrentPin++)\r\n        {\r\n            pOutputPin = (CDynamicSourceStream*) GetPin(nCurrentPin);\r\n            pOutputPin->SetConfigInfo(pGraphConfig, m_evFilterStoppingEvent);\r\n        }\r\n\r\n        pGraphConfig->Release();\r\n    }\r\n    else\r\n    {\r\n        hr = CBaseFilter::JoinFilterGraph(pGraph, pName);\r\n        if(FAILED(hr))\r\n        {\r\n            return hr;\r\n        }\r\n\r\n        for(nCurrentPin = 0; nCurrentPin < GetPinCount(); nCurrentPin++)\r\n        {\r\n            pOutputPin = (CDynamicSourceStream*)GetPin(nCurrentPin);\r\n            pOutputPin->SetConfigInfo(NULL, NULL);\r\n        }\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n// *\r\n// * --- CDynamicSourceStream ----\r\n// *\r\n\r\n//\r\n// Set Id to point to a CoTaskMemAlloc'd\r\nSTDMETHODIMP CDynamicSourceStream::QueryId(LPWSTR *pId)\r\n{\r\n    CheckPointer(pId,E_POINTER);\r\n    ValidateReadWritePtr(pId,sizeof(LPWSTR));\r\n\r\n    // We give the pins id's which are 1,2,...\r\n    // FindPinNumber returns -1 for an invalid pin\r\n    int i = 1+ m_pFilter->FindPinNumber(this);\r\n\r\n    if(i<1) \r\n        return VFW_E_NOT_FOUND;\r\n\r\n    *pId = (LPWSTR)CoTaskMemAlloc(4*sizeof(WCHAR));\r\n    if(*pId==NULL)\r\n    {\r\n        return E_OUTOFMEMORY;\r\n    }\r\n\r\n    IntToWstr(i, *pId);\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// CDynamicSourceStream::Constructor\r\n//\r\n// increments the number of pins present on the filter\r\nCDynamicSourceStream::CDynamicSourceStream(\r\n    TCHAR *pObjectName,\r\n    HRESULT *phr,\r\n    CDynamicSource*ps,\r\n    LPCWSTR pPinName)\r\n    : CDynamicOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),\r\n      m_pFilter(ps),\r\n      m_fReconnectOutputPin(false)\r\n{\r\n    ASSERT(phr);   \r\n    *phr = m_pFilter->AddPin(this);\r\n}\r\n\r\n\r\n#ifdef UNICODE\r\n\r\nCDynamicSourceStream::CDynamicSourceStream(\r\n    char *pObjectName,\r\n    HRESULT *phr,\r\n    CDynamicSource*ps,\r\n    LPCWSTR pPinName)\r\n    : CDynamicOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),\r\n      m_pFilter(ps),\r\n      m_fReconnectOutputPin(false)\r\n{\r\n    ASSERT(phr);\r\n    *phr = m_pFilter->AddPin(this);\r\n}\r\n\r\n#endif\r\n\r\n\r\n//\r\n// CDynamicSourceStream::Destructor\r\n//\r\n// Decrements the number of pins on this filter\r\nCDynamicSourceStream::~CDynamicSourceStream(void)\r\n{\r\n    m_pFilter->RemovePin(this);\r\n}\r\n\r\n\r\n//\r\n// CheckMediaType\r\n//\r\n// Do we support this type? Provides the default support for 1 type.\r\nHRESULT CDynamicSourceStream::CheckMediaType(const CMediaType *pMediaType)\r\n{\r\n    CheckPointer(pMediaType,E_POINTER);\r\n    CAutoLock lock(m_pFilter->pStateLock());\r\n\r\n    CMediaType mt;\r\n    GetMediaType(&mt);\r\n\r\n    if(mt == *pMediaType)\r\n    {\r\n        return NOERROR;\r\n    }\r\n\r\n    return E_FAIL;\r\n}\r\n\r\n\r\n//\r\n// GetMediaType\r\n//\r\n// By default we support only one type\r\n// iPosition indexes are 0-n\r\nHRESULT CDynamicSourceStream::GetMediaType(int iPosition, CMediaType *pMediaType)\r\n{\r\n    CAutoLock lock(m_pFilter->pStateLock());\r\n\r\n    if(iPosition<0)\r\n    {\r\n        return E_INVALIDARG;\r\n    }\r\n    if(iPosition>0)\r\n    {\r\n        return VFW_S_NO_MORE_ITEMS;\r\n    }\r\n\r\n    return GetMediaType(pMediaType);\r\n}\r\n\r\n\r\n//\r\n// Active\r\n//\r\n// The pin is active - start up the worker thread\r\nHRESULT CDynamicSourceStream::Active(void)\r\n{\r\n    CAutoLock lock(m_pFilter->pStateLock());\r\n\r\n    HRESULT hr;\r\n\r\n    if(m_pFilter->IsActive())\r\n    {\r\n        return S_FALSE; // succeeded, but did not allocate resources (they already exist...)\r\n    }\r\n\r\n    // do nothing if not connected - its ok not to connect to\r\n    // all pins of a source filter\r\n    if(!IsConnected())\r\n    {\r\n        return NOERROR;\r\n    }\r\n\r\n    hr = CDynamicOutputPin::Active();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    ASSERT(!ThreadExists());\r\n\r\n    // start the thread\r\n    if(!Create())\r\n    {\r\n        return E_FAIL;\r\n    }\r\n\r\n    // Tell thread to initialize. If OnThreadCreate Fails, so does this.\r\n    hr = Init();\r\n    if(FAILED(hr))\r\n        return hr;\r\n\r\n    return Pause();\r\n}\r\n\r\n\r\nHRESULT CDynamicSourceStream::BreakConnect(void)\r\n{\r\n    HRESULT hr = CDynamicOutputPin::BreakConnect();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    m_fReconnectOutputPin = false;\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\nHRESULT CDynamicSourceStream::DestroySourceThread(void)\r\n{\r\n    // The pin's thread cannot be destroyed if the thread does not exist.\r\n    ASSERT(ThreadExists());\r\n\r\n    HRESULT hr = Stop();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    hr = Exit();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    Close();    // Wait for the thread to exit, then tidy up.\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// ThreadProc\r\n//\r\n// When this returns the thread exits\r\n// Return codes > 0 indicate an error occured\r\nDWORD CDynamicSourceStream::ThreadProc(void)\r\n{\r\n    HRESULT hr;  // the return code from calls\r\n    Command com;\r\n\r\n    do\r\n    {\r\n        com = GetRequest();\r\n        if(com != CMD_INIT)\r\n        {\r\n            DbgLog((LOG_ERROR, 1, TEXT(\"Thread expected init command\")));\r\n            Reply((DWORD) E_UNEXPECTED);\r\n        }\r\n\r\n    } while(com != CMD_INIT);\r\n\r\n    DbgLog((LOG_TRACE, 1, TEXT(\"CDynamicSourceStream worker thread initializing\")));\r\n\r\n    hr = OnThreadCreate(); // perform set up tasks\r\n    if(FAILED(hr))\r\n    {\r\n        DbgLog((LOG_ERROR, 1, TEXT(\"CDynamicSourceStream::OnThreadCreate failed. Aborting thread.\")));\r\n\r\n        OnThreadDestroy();\r\n        Reply(hr);  // send failed return code from OnThreadCreate\r\n        return 1;\r\n    }\r\n\r\n    // Initialisation suceeded\r\n    Reply(NOERROR);\r\n\r\n    Command cmd;\r\n    do\r\n    {\r\n        cmd = GetRequest();\r\n\r\n        switch(cmd)\r\n        {\r\n            case CMD_EXIT:\r\n                Reply(NOERROR);\r\n                break;\r\n\r\n            case CMD_RUN:\r\n                DbgLog((LOG_ERROR, 1, TEXT(\"CMD_RUN received before a CMD_PAUSE???\")));\r\n                // !!! fall through\r\n\r\n            case CMD_PAUSE:\r\n                Reply(NOERROR);\r\n                DoBufferProcessingLoop();\r\n                break;\r\n\r\n            case CMD_STOP:\r\n                Reply(NOERROR);\r\n                break;\r\n\r\n            default:\r\n                DbgLog((LOG_ERROR, 1, TEXT(\"Unknown command %d received!\"), cmd));\r\n                Reply((DWORD) E_NOTIMPL);\r\n                break;\r\n        }\r\n\r\n    } while(cmd != CMD_EXIT);\r\n\r\n    hr = OnThreadDestroy(); // tidy up.\r\n    if(FAILED(hr))\r\n    {\r\n        DbgLog((LOG_ERROR, 1, TEXT(\"CDynamicSourceStream::OnThreadDestroy failed. Exiting thread.\")));\r\n        return 1;\r\n    }\r\n\r\n    DbgLog((LOG_TRACE, 1, TEXT(\"CDynamicSourceStream worker thread exiting\")));\r\n    return 0;\r\n}\r\n\r\n\r\n//\r\n// DoBufferProcessingLoop\r\n//\r\n// Grabs a buffer and calls the users processing function.\r\n// Overridable, so that different delivery styles can be catered for.\r\nHRESULT CDynamicSourceStream::DoBufferProcessingLoop(void)\r\n{\r\n    Command com;\r\n    bool fOutputFormatChanged = false;\r\n\r\n    OnThreadStartPlay();\r\n\r\n    do\r\n    {\r\n        while(!CheckRequest(&com))\r\n        {\r\n            // CAutoUsingOutputPin::CAutoUsingOutputPin() only changes the value of hr\r\n            // if an error occurs.\r\n            HRESULT hr = S_OK;\r\n\r\n            CAutoUsingOutputPin auopUsingOutputPin(this, &hr);\r\n            if(FAILED(hr))\r\n            {\r\n                FatalError(hr);\r\n                return hr;\r\n            }\r\n\r\n            if(m_fReconnectOutputPin)\r\n            {\r\n                hr = DynamicReconnect(NULL);\r\n\r\n                m_fReconnectOutputPin = false;\r\n\r\n                if(FAILED(hr))\r\n                {\r\n                    FatalError(hr);\r\n                    return hr;\r\n                }\r\n\r\n                fOutputFormatChanged = true;\r\n            }\r\n\r\n            IMediaSample *pSample;\r\n\r\n            hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);\r\n            if(FAILED(hr))\r\n            {\r\n                Sleep(1);\r\n                continue;   // go round again. Perhaps the error will go away\r\n                // or the allocator is decommited & we will be asked to\r\n                // exit soon.\r\n            }\r\n\r\n            if(fOutputFormatChanged)\r\n            {\r\n                pSample->SetDiscontinuity(TRUE);\r\n                fOutputFormatChanged = false;\r\n            }\r\n\r\n            // Virtual function user will override.\r\n            hr = FillBuffer(pSample);\r\n\r\n            if(hr == S_OK)\r\n            {\r\n                hr = Deliver(pSample);\r\n                pSample->Release();\r\n\r\n                // downstream filter returns S_FALSE if it wants us to\r\n                // stop or an error if it's reporting an error.\r\n                if(hr != S_OK)\r\n                {\r\n                    DbgLog((LOG_TRACE, 2, TEXT(\"Deliver() returned %08x; stopping\"), hr));\r\n                    return S_OK;\r\n                }\r\n\r\n            }\r\n            else if(hr == S_FALSE)\r\n            {\r\n                // derived class wants us to stop pushing data\r\n                pSample->Release();\r\n                DeliverEndOfStream();\r\n                return S_OK;\r\n            }\r\n            else\r\n            {\r\n                // derived class encountered an error\r\n                pSample->Release();\r\n                DbgLog((LOG_ERROR, 1, TEXT(\"Error %08lX from FillBuffer!!!\"), hr));\r\n\r\n                FatalError(hr);\r\n                return hr;\r\n            }\r\n            // all paths release the sample\r\n        }\r\n\r\n        // For all commands sent to us there must be a Reply call!\r\n        if(com == CMD_RUN || com == CMD_PAUSE)\r\n        {\r\n            Reply(NOERROR);\r\n        }\r\n        else if(com != CMD_STOP)\r\n        {\r\n            Reply((DWORD) E_UNEXPECTED);\r\n            DbgLog((LOG_ERROR, 1, TEXT(\"Unexpected command!!!\")));\r\n        }\r\n    } while(com != CMD_STOP);\r\n\r\n    return S_FALSE;\r\n}\r\n\r\n\r\nvoid CDynamicSourceStream::FatalError(HRESULT hr)\r\n{\r\n    // Make sure the user is reporting a failure.\r\n    ASSERT(FAILED(hr));\r\n\r\n    m_bRunTimeError = TRUE;\r\n    DeliverEndOfStream();\r\n    m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);\r\n}\r\n\r\n\r\nvoid CDynamicSourceStream::OutputPinNeedsToBeReconnected(void)\r\n{\r\n    m_fReconnectOutputPin = true;\r\n}\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/dynsrc.h",
    "content": "//------------------------------------------------------------------------------\r\n// File: DynSrc.h\r\n//\r\n// Desc: DirectShow sample code - defines classes to simplify creation of\r\n//       ActiveX source filters that support continuous generation of data.\r\n//       No support is provided for IMediaControl or IMediaPosition.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\n//\r\n// Derive your source filter from CDynamicSource.\r\n// During construction either:\r\n//    Create some CDynamicSourceStream objects to manage your pins\r\n//    Provide the user with a means of doing so eg, an IPersistFile interface.\r\n//\r\n// CDynamicSource provides:\r\n//    IBaseFilter interface management\r\n//    IMediaFilter interface management, via CBaseFilter\r\n//    Pin counting for CBaseFilter\r\n//\r\n// Derive a class from CDynamicSourceStream to manage your output pin types\r\n//  Implement GetMediaType/1 to return the type you support. If you support multiple\r\n//   types then overide GetMediaType/3, CheckMediaType and GetMediaTypeCount.\r\n//  Implement Fillbuffer() to put data into one buffer.\r\n//\r\n// CDynamicSourceStream provides:\r\n//    IPin management via CDynamicOutputPin\r\n//    Worker thread management\r\n\r\n#ifndef __CDYNAMICSOURCE__\r\n#define __CDYNAMICSOURCE__\r\n\r\nclass CDynamicSourceStream;  // The class that will handle each pin\r\n\r\n\r\n//\r\n// CDynamicSource\r\n//\r\n// Override construction to provide a means of creating\r\n// CDynamicSourceStream derived objects - ie a way of creating pins.\r\nclass CDynamicSource: public CBaseFilter {\r\npublic:\r\n\r\n    CDynamicSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);\r\n#ifdef UNICODE\r\n    CDynamicSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);\r\n#endif\r\n    ~CDynamicSource();\r\n\r\n    int       GetPinCount(void);\r\n    CBasePin *GetPin(int n);\r\n\r\n    // -- Utilities --\r\n\r\n    CCritSec*   pStateLock(void) { return &m_cStateLock; }  // provide our critical section\r\n\r\n    HRESULT     AddPin(CDynamicSourceStream *);\r\n    HRESULT     RemovePin(CDynamicSourceStream *);\r\n\r\n    STDMETHODIMP FindPin(\r\n        LPCWSTR Id,\r\n        IPin ** ppPin\r\n    );\r\n\r\n    int FindPinNumber(IPin *iPin);\r\n    \r\n    STDMETHODIMP JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName);\r\n    STDMETHODIMP Stop(void);\r\n    STDMETHODIMP Pause(void);\r\n    \r\nprotected:\r\n\r\n    CAMEvent m_evFilterStoppingEvent;\r\n\r\n    int m_iPins;    // The number of pins on this filter. Updated by \r\n                    // CDynamicSourceStream constructors & destructors.\r\n                    \r\n    CDynamicSourceStream **m_paStreams;   // the pins on this filter.\r\n\r\n    // This lock must be held when m_paStreams or m_iPins\r\n    // is being used.  The state lock (m_cStateLock) must \r\n    // also be held if the program wants to change the value\r\n    // of m_paStreams or m_iPins.  Functions cannot acquire \r\n    // the state lock (m_cStateLock) after they acquire\r\n    // m_csPinStateLock.  The program will deadlock if it\r\n    // violates this rule.  Also the program may not acquire\r\n    // m_csPinStateLock on the streaming thread.  If it does,\r\n    // the program will deadlock.  The streaming thread calls\r\n    // ThreadProc() and DoBufferProcessingLoop().\r\n    CCritSec m_csPinStateLock;\r\n\r\n    // This lock serializes accesses to the filter's state.\r\n    // It also must be held when the program changes \r\n    // m_iPins's or m_paStreams's value.\r\n    CCritSec m_cStateLock;\r\n\r\n};\r\n\r\n\r\n//\r\n// CDynamicSourceStream\r\n//\r\n// Use this class to manage a stream of data that comes from a\r\n// pin.\r\n// Uses a worker thread to put data on the pin.\r\nclass CDynamicSourceStream : public CAMThread, public CDynamicOutputPin {\r\npublic:\r\n\r\n    CDynamicSourceStream(TCHAR *pObjectName,\r\n                         HRESULT *phr,\r\n                         CDynamicSource*pms,\r\n                         LPCWSTR pName);\r\n#ifdef UNICODE\r\n    CDynamicSourceStream(CHAR *pObjectName,\r\n                         HRESULT *phr,\r\n                         CDynamicSource*pms,\r\n                         LPCWSTR pName);\r\n#endif\r\n    virtual ~CDynamicSourceStream(void);  // virtual destructor ensures derived \r\n                                          // class destructors are called too\r\n\r\n    HRESULT DestroySourceThread(void);\r\n\r\nprotected:\r\n\r\n    CDynamicSource*m_pFilter;             // The parent of this stream\r\n\r\n    // *\r\n    // * Data Source\r\n    // *\r\n    // * The following three functions: FillBuffer, OnThreadCreate/Destroy, are\r\n    // * called from within the ThreadProc. They are used in the creation of\r\n    // * the media samples this pin will provide\r\n    // *\r\n\r\n    // Override this to provide the worker thread a means\r\n    // of processing a buffer\r\n    virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE;\r\n\r\n    // Called as the thread is created/destroyed - use to perform\r\n    // jobs such as start/stop streaming mode\r\n    // If OnThreadCreate returns an error the thread will exit.\r\n    virtual HRESULT OnThreadCreate(void) {return NOERROR;};\r\n    virtual HRESULT OnThreadDestroy(void) {return NOERROR;};\r\n    virtual HRESULT OnThreadStartPlay(void) {return NOERROR;};\r\n\r\n    // *\r\n    // * Worker Thread\r\n    // *\r\n\r\n    HRESULT Active(void);    // Starts up the worker thread\r\n\r\n    HRESULT BreakConnect(void);\r\n\r\npublic:\r\n    // thread commands\r\n    enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT};\r\n\r\n    HRESULT Init(void) { return CallWorker(CMD_INIT); }\r\n    HRESULT Exit(void) { return CallWorker(CMD_EXIT); }\r\n    HRESULT Run(void) { return CallWorker(CMD_RUN); }\r\n    HRESULT Pause(void) { return CallWorker(CMD_PAUSE); }\r\n    HRESULT Stop(void) { return CallWorker(CMD_STOP); }\r\n\r\n    void OutputPinNeedsToBeReconnected(void);\r\n\r\nprotected:\r\n    Command GetRequest(void) { return (Command) CAMThread::GetRequest(); }\r\n    BOOL    CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); }\r\n\r\n    // override these if you want to add thread commands\r\n    virtual DWORD ThreadProc(void);         // the thread function\r\n\r\n    virtual HRESULT DoBufferProcessingLoop(void);    // the loop executed whilst running\r\n    \r\n    void FatalError(HRESULT hr);\r\n\r\n    // *\r\n    // * AM_MEDIA_TYPE support\r\n    // *\r\n\r\n    // If you support more than one media type then override these 2 functions\r\n    virtual HRESULT CheckMediaType(const CMediaType *pMediaType);\r\n    virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);  // List pos. 0-n\r\n\r\n    // If you support only one type then override this fn.\r\n    // This will only be called by the default implementations\r\n    // of CheckMediaType and GetMediaType(int, CMediaType*)\r\n    // You must override this fn. or the above 2!\r\n    virtual HRESULT GetMediaType(CMediaType *pMediaType) {return E_UNEXPECTED;}\r\n\r\n    STDMETHODIMP QueryId(\r\n        LPWSTR * Id\r\n    );\r\n\r\n    bool m_fReconnectOutputPin;\r\n};\r\n    \r\n#endif // __CDYNAMICSOURCE__\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/isynth.h",
    "content": "//------------------------------------------------------------------------------\r\n// File: ISynth.h\r\n//\r\n// Desc: DirectShow sample code - custom interface to allow the user to\r\n//       adjust the frequency.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\n#ifndef __ISYNTH2__\r\n#define __ISYNTH2__\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n\r\n//\r\n// ISynth2's GUID\r\n//\r\n// {00487A78-D875-44b0-ADBB-DECA9CDB51FC}\r\nDEFINE_GUID(IID_ISynth2, \r\n0x487a78, 0xd875, 0x44b0, 0xad, 0xbb, 0xde, 0xca, 0x9c, 0xdb, 0x51, 0xfc);\r\n\r\nenum SYNTH_OUTPUT_FORMAT\r\n{\r\n    SYNTH_OF_PCM,\r\n    SYNTH_OF_MS_ADPCM\r\n};\r\n\r\n//\r\n// ISynth2\r\n//\r\nDECLARE_INTERFACE_(ISynth2, IUnknown) {\r\n\r\n    STDMETHOD(get_Frequency) (THIS_\r\n                int *Frequency          /* [out] */    // the current frequency\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_Frequency) (THIS_\r\n                int    Frequency        /* [in] */    // Change to this frequency\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_Waveform) (THIS_\r\n                int *Waveform           /* [out] */    // the current Waveform\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_Waveform) (THIS_\r\n                int    Waveform         /* [in] */    // Change to this Waveform\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_Channels) (THIS_\r\n                int *Channels           /* [out] */   // the current Channels\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_Channels) (THIS_\r\n                int    Channels         /* [in] */    // Change to this Channels\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_BitsPerSample) (THIS_\r\n                int *BitsPerSample      /* [out] */   // the current BitsPerSample\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_BitsPerSample) (THIS_\r\n                int    BitsPerSample    /* [in] */    // Change to this BitsPerSample\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_SamplesPerSec) (THIS_\r\n                 int *SamplesPerSec     /* [out] */   // the current SamplesPerSec\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_SamplesPerSec) (THIS_\r\n                  int    SamplesPerSec  /* [in] */    // Change to this SamplesPerSec\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_Amplitude) (THIS_\r\n                  int *Amplitude        /* [out] */   // the current Amplitude\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_Amplitude) (THIS_\r\n                  int    Amplitude      /* [in] */    // Change to this Amplitude\r\n              ) PURE;\r\n\r\n    STDMETHOD(get_SweepRange) (THIS_\r\n                  int *SweepStart,      /* [out] */\r\n                  int *SweepEnd         /* [out] */\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_SweepRange) (THIS_\r\n                  int    SweepStart,    /* [in] */\r\n                  int    SweepEnd       /* [in] */\r\n             ) PURE;\r\n\r\n    STDMETHOD(get_OutputFormat) (THIS_\r\n                  SYNTH_OUTPUT_FORMAT *pOutputFormat /* [out] */\r\n             ) PURE;\r\n\r\n    STDMETHOD(put_OutputFormat) (THIS_\r\n                  SYNTH_OUTPUT_FORMAT ofNewOutputFormat /* [out] */\r\n             ) PURE;\r\n    \r\n};\r\n\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif // __ISYNTH2__\r\n\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/loopback-capture-helpers.cpp",
    "content": "\r\n#include <windows.h>\r\n#include <mmsystem.h>\r\n#include <mmdeviceapi.h>\r\n#include <audioclient.h>\r\n#include <stdio.h>\r\n#include <avrt.h>\r\n#include <stdio.h>\r\n\r\nHRESULT open_file(LPCWSTR szFileName, HMMIO *phFile) {\r\n    MMIOINFO mi = {0};\r\n\r\n    *phFile = mmioOpen(\r\n        // some flags cause mmioOpen write to this buffer\r\n        // but not any that we're using\r\n        const_cast<LPWSTR>(szFileName),\r\n        &mi,\r\n        MMIO_WRITE | MMIO_CREATE\r\n    );\r\n\r\n    if (NULL == *phFile) {\r\n        printf(\"mmioOpen(\\\"%ls\\\", ...) failed. wErrorRet == %u\\n\", szFileName, mi.wErrorRet);\r\n        return E_FAIL;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\nHRESULT get_default_device(IMMDevice **ppMMDevice) {\r\n    HRESULT hr = S_OK;\r\n    IMMDeviceEnumerator *pMMDeviceEnumerator;\r\n    // activate a device enumerator\r\n    hr = CoCreateInstance(\r\n        __uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, \r\n        __uuidof(IMMDeviceEnumerator),\r\n        (void**)&pMMDeviceEnumerator\r\n    );\r\n    if (FAILED(hr)) {\r\n        printf(\"CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x\\n\", hr);\r\n        return hr;\r\n    }\r\n\r\n    // get the default render endpoint\r\n    hr = pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, ppMMDevice);\r\n    pMMDeviceEnumerator->Release();\r\n    if (FAILED(hr)) {\r\n        printf(\"IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: hr = 0x%08x\\n\", hr);\r\n        return hr;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n"
  },
  {
    "path": "source_code/synth_deprecated/loopback-capture.cpp",
    "content": "#include <windows.h>\r\n\r\n\r\n#include <mmsystem.h>\r\n#include <mmdeviceapi.h>\r\n#include <audioclient.h>\r\n#include <stdio.h>\r\n#include <avrt.h>\r\n\r\nHRESULT open_file(LPCWSTR szFileName, HMMIO *phFile);\r\n\r\nHRESULT get_default_device(IMMDevice **ppMMDevice);\r\n\r\n// size is size of the BYTE buffer...but...I guess...we just have to fill it all the way with data...I guess...\r\nHRESULT LoopbackCapture(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize, WAVEFORMATEX* ifNotNullThenJustSetTypeOnly)\r\n {\r\n\tbool bInt16 = true; // makes it actually work, for some reason...\r\n\r\n\tUINT32 pnFrames = 0;\r\n\r\n    HRESULT hr;\r\n    IMMDevice *m_pMMDevice;\r\n    hr = get_default_device(&m_pMMDevice); // so it can re-place our pointer...\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    // activate an (the default, for us) IAudioClient\r\n    IAudioClient *pAudioClient;\r\n    hr = m_pMMDevice->Activate(\r\n        __uuidof(IAudioClient),\r\n        CLSCTX_ALL, NULL,\r\n        (void**)&pAudioClient\r\n    );\r\n    if (FAILED(hr)) {\r\n        printf(\"IMMDevice::Activate(IAudioClient) failed: hr = 0x%08x\", hr);\r\n        return hr;\r\n    }\r\n    \r\n    // get the default device periodicity\r\n    REFERENCE_TIME hnsDefaultDevicePeriod;\r\n    hr = pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, NULL);\r\n    if (FAILED(hr)) {\r\n        printf(\"IAudioClient::GetDevicePeriod failed: hr = 0x%08x\\n\", hr);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n\r\n    // get the default device format (incoming...)\r\n    WAVEFORMATEX *pwfx; // incoming wave...\r\n    hr = pAudioClient->GetMixFormat(&pwfx);\r\n    if (FAILED(hr)) {\r\n        printf(\"IAudioClient::GetMixFormat failed: hr = 0x%08x\\n\", hr);\r\n        CoTaskMemFree(pwfx);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n\r\n    if (bInt16) {\r\n        // coerce int-16 wave format\r\n        // can do this in-place since we're not changing the size of the format\r\n        // also, the engine will auto-convert from float to int for us\r\n        switch (pwfx->wFormatTag) {\r\n            case WAVE_FORMAT_IEEE_FLOAT:\r\n                pwfx->wFormatTag = WAVE_FORMAT_PCM;\r\n                pwfx->wBitsPerSample = 16;\r\n                pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;\r\n                pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;\r\n                break;\r\n\r\n            case WAVE_FORMAT_EXTENSIBLE:\r\n                {\r\n                    // naked scope for case-local variable\r\n                    PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);\r\n                    if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat)) {\r\n\t\t\t\t\t\t// WE GET HERE!\r\n                        pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;\r\n                        pEx->Samples.wValidBitsPerSample = 16;\r\n                        pwfx->wBitsPerSample = 16;\r\n                        pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;\r\n                        pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;\r\n                    } else {\r\n                        printf(\"Don't know how to coerce mix format to int-16\\n\");\r\n                        CoTaskMemFree(pwfx);\r\n                        pAudioClient->Release();\r\n                        return E_UNEXPECTED;\r\n                    }\r\n                }\r\n                break;\r\n\r\n            default:\r\n                printf(\"Don't know how to coerce WAVEFORMATEX with wFormatTag = 0x%08x to int-16\\n\", pwfx->wFormatTag);\r\n                CoTaskMemFree(pwfx);\r\n                pAudioClient->Release();\r\n                return E_UNEXPECTED;\r\n        }\r\n    }\r\n\r\n\tif(ifNotNullThenJustSetTypeOnly) {\r\n\t\t// pwfx is set at this point...\r\n\t\tWAVEFORMATEX* pwfex = ifNotNullThenJustSetTypeOnly;\r\n\t\t// copy them all out as the possible format...hmm...\r\n\r\n\r\n\t\t                pwfx->wFormatTag = WAVE_FORMAT_PCM;\r\n                pwfx->wBitsPerSample = 16;\r\n                pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;\r\n                pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;\r\n\r\n\r\n\t\tpwfex->wFormatTag = pwfx->wFormatTag;\r\n\t\tpwfex->nChannels = pwfx->nChannels;\r\n        pwfex->nSamplesPerSec = pwfx->nSamplesPerSec;\r\n        pwfex->wBitsPerSample = pwfx->wBitsPerSample;\r\n        pwfex->nBlockAlign = pwfx->nBlockAlign;\r\n        pwfex->nAvgBytesPerSec = pwfx->nAvgBytesPerSec;\r\n        pwfex->cbSize = pwfx->cbSize;\r\n\t\t//FILE *fp = fopen(\"/normal2\", \"w\"); // fails on me? maybe juts a VLC thing...\r\n\t\t//fprintf(fp, \"hello world %d %d %d %d %d %d %d\", pwfex->wFormatTag, pwfex->nChannels, \r\n\t\t//\tpwfex->nSamplesPerSec, pwfex->wBitsPerSample, pwfex->nBlockAlign, pwfex->nAvgBytesPerSec, pwfex->cbSize );\r\n\t\t//fclose(fp);\r\n\t\t// cleanup\r\n\t\t// I might be leaking here...\r\n        m_pMMDevice->Release();\r\n\t\treturn hr;\r\n\t}\r\n\r\n    MMCKINFO ckRIFF = {0};\r\n    MMCKINFO ckData = {0};\r\n\r\n    // create a periodic waitable timer\r\n\t\r\n    UINT32 nBlockAlign = pwfx->nBlockAlign;\r\n    \r\n    // call IAudioClient::Initialize\r\n    // note that AUDCLNT_STREAMFLAGS_LOOPBACK and AUDCLNT_STREAMFLAGS_EVENTCALLBACK\r\n    // do not work together...\r\n    // the \"data ready\" event never gets set\r\n    // so we're going to do a timer-driven loop...\r\n    hr = pAudioClient->Initialize(\r\n        AUDCLNT_SHAREMODE_SHARED,\r\n        AUDCLNT_STREAMFLAGS_LOOPBACK,\r\n        0, 0, pwfx, 0\r\n    );\r\n    if (FAILED(hr)) {\r\n        printf(\"IAudioClient::Initialize failed: hr = 0x%08x\\n\", hr);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    CoTaskMemFree(pwfx);\r\n\r\n    // activate an IAudioCaptureClient\r\n    IAudioCaptureClient *pAudioCaptureClient;\r\n    hr = pAudioClient->GetService(\r\n        __uuidof(IAudioCaptureClient),\r\n        (void**)&pAudioCaptureClient\r\n    );\r\n    if (FAILED(hr)) {\r\n        printf(\"IAudioClient::GetService(IAudioCaptureClient) failed: hr 0x%08x\\n\", hr);\r\n        //CloseHandle(hWakeUp);\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    \r\n    // register with MMCSS\r\n    DWORD nTaskIndex = 0;\r\n    HANDLE hTask = AvSetMmThreadCharacteristics(L\"Capture\", &nTaskIndex);\r\n    if (NULL == hTask) {\r\n        DWORD dwErr = GetLastError();\r\n        printf(\"AvSetMmThreadCharacteristics failed: last error = %u\\n\", dwErr);\r\n        pAudioCaptureClient->Release();\r\n        //CloseHandle(hWakeUp);\r\n        pAudioClient->Release();\r\n        return HRESULT_FROM_WIN32(dwErr);\r\n    }    \r\n\r\n    // call IAudioClient::Start\r\n    hr = pAudioClient->Start();\r\n    if (FAILED(hr)) {\r\n        printf(\"IAudioClient::Start failed: hr = 0x%08x\\n\", hr);\r\n        AvRevertMmThreadCharacteristics(hTask);\r\n        pAudioCaptureClient->Release();\r\n        pAudioClient->Release();\r\n        return hr;\r\n    }\r\n    \r\n    bool bDone = false;\r\n    bool bFirstPacket = true;\r\n\r\n\r\n    // loop forever until bDone is set by the keyboard\r\n    for (UINT32 nBitsWrote = 0; nBitsWrote < iSize; ) {\r\n\r\n        // TODO sleep until there is data available [?] or can it poll me... [lodo]\r\n        UINT32 nNextPacketSize;\r\n        hr = pAudioCaptureClient->GetNextPacketSize(&nNextPacketSize);\r\n        if (FAILED(hr)) {\r\n            printf(\"IAudioCaptureClient::GetNextPacketSize failed on pass %u after %u frames: hr = 0x%08x\\n\", nBitsWrote, pnFrames, hr);\r\n            pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();            \r\n            return hr;\r\n        }\r\n\r\n        if (0 == nNextPacketSize) {\r\n            // no data yet\r\n\t\t\tSleep(0);// LODO (?)\r\n            continue;\r\n        }\r\n\r\n        // get the captured data\r\n        BYTE *pData;\r\n        UINT32 nNumFramesToRead;\r\n        DWORD dwFlags;\r\n\r\n\t\t// I guess it gives us...umm...as much as possible?\r\n\r\n        hr = pAudioCaptureClient->GetBuffer(\r\n            &pData,\r\n            &nNumFramesToRead,\r\n            &dwFlags,\r\n            NULL,\r\n            NULL\r\n        ); // ACTUALLY GET THE BUFFER which I assume it reads in the format of the fella we passed in\r\n        // so...it reads nNumFrames and calls it good or what?\r\n        \r\n        \r\n        if (FAILED(hr)) {\r\n            printf(\"IAudioCaptureClient::GetBuffer failed on pass %u after %u frames: hr = 0x%08x\\n\", nBitsWrote, pnFrames, hr);\r\n            pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();            \r\n            return hr;            \r\n        }\r\n\r\n        if (bFirstPacket && AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY == dwFlags) {\r\n            printf(\"Probably spurious glitch reported on first packet\\n\");\r\n        } else if (0 != dwFlags) {\r\n            printf(\"IAudioCaptureClient::GetBuffer set flags to 0x%08x on pass %u after %u frames\\n\", dwFlags, nBitsWrote, pnFrames);\r\n            pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();            \r\n            return E_UNEXPECTED;\r\n        }\r\n\r\n        if (0 == nNumFramesToRead) {\r\n            printf(\"IAudioCaptureClient::GetBuffer said to read 0 frames on pass %u after %u frames\\n\", nBitsWrote, pnFrames);\r\n            pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();            \r\n            return E_UNEXPECTED;            \r\n        } else {\r\n\t\t\tpnFrames += nNumFramesToRead; // increment total count...\r\n\t\t}\r\n\r\n        LONG lBytesToWrite = nNumFramesToRead * nBlockAlign;\r\n#pragma prefast(suppress: __WARNING_INCORRECT_ANNOTATION, \"IAudioCaptureClient::GetBuffer SAL annotation implies a 1-byte buffer\")\r\n        // TODO WRITE TO OUTGOING [?]\r\n\t\tfor(int i = 0; i < lBytesToWrite && nBitsWrote < iSize;i++) {\r\n\r\n\t\t\tpBuf[nBitsWrote++] = pData[i]; // lodo use a straight call...\r\n\r\n\t\t}\r\n        \r\n        hr = pAudioCaptureClient->ReleaseBuffer(nNumFramesToRead);\r\n        if (FAILED(hr)) {\r\n            printf(\"IAudioCaptureClient::ReleaseBuffer failed on pass %u after %u frames: hr = 0x%08x\\n\", nBitsWrote, pnFrames, hr);\r\n            pAudioClient->Stop();\r\n            AvRevertMmThreadCharacteristics(hTask);\r\n            pAudioCaptureClient->Release();\r\n            pAudioClient->Release();            \r\n            return hr;            \r\n        }\r\n        \r\n        bFirstPacket = false;\r\n    } // capture loop...\r\n\r\n    pAudioClient->Stop();\r\n    AvRevertMmThreadCharacteristics(hTask);\r\n    pAudioCaptureClient->Release();\r\n    pAudioClient->Release();\r\n    m_pMMDevice->Release();\r\n    return hr;\r\n}\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/resource.h",
    "content": "//\r\n// Microsoft Visual C++ generated include file.\r\n// Used by synth.rc\r\n//\r\n\r\n#define IDD_BALLPROP                    101\r\n#define IDD_SYNTHPROP1                  101\r\n#define IDC_FREQUENCYTEXT               1002\r\n#define IDC_FREQUENCY                   1003\r\n#define IDC_AMPLITUDETEXT               1003\r\n#define IDC_FREQTRACKBAR                1004\r\n#define IDC_FREQUENCYGROUP              1005\r\n#define IDC_WAVEFORMGROUP               1006\r\n#define IDC_WAVESINE                    1007\r\n#define IDC_WAVESQUARE                  1008\r\n#define IDC_WAVESAWTOOTH                1009\r\n#define IDC_WAVESWEEP                   1010\r\n#define IDC_AMPLITUDETRACKBAR           1011\r\n#define IDC_CHANNELS1                   1012\r\n#define IDC_CHANNELS2                   1013\r\n#define IDC_BITSPERSAMPLEGROUP          1014\r\n#define IDC_BITSPERSAMPLE8              1015\r\n#define IDC_BITSPERSAMPLE16             1016\r\n#define IDC_SAMPLINGFREQUENCYGROUP      1017\r\n#define IDC_SAMPLINGFREQ11              1018\r\n#define IDC_SAMPLINGFREQ22              1019\r\n#define IDC_SAMPLINGFREQ44              1020\r\n#define IDC_AMPLITUDEGROUP              1021\r\n#define IDC_SWEEP                       1023\r\n#define IDS_SYNTHPROPNAME               1024\r\n#define IDC_OUTPUTFORMAT                1025\r\n#define IDC_OF_PCM                      1026\r\n#define IDC_OF_MSADPCM                  1027\r\n\r\n#define IDS_STATIC                      -1\r\n#define IDC_CHANNELSGROUP               -1\r\n\r\n// Next default values for new objects\r\n// \r\n#ifdef APSTUDIO_INVOKED\r\n#ifndef APSTUDIO_READONLY_SYMBOLS\r\n#define _APS_NO_MFC                     1\r\n#define _APS_3D_CONTROLS                1\r\n#define _APS_NEXT_RESOURCE_VALUE        102\r\n#define _APS_NEXT_COMMAND_VALUE         40001\r\n#define _APS_NEXT_CONTROL_VALUE         1027\r\n#define _APS_NEXT_SYMED_VALUE           101\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.cpp",
    "content": "//------------------------------------------------------------------------------\r\n// File: Synth.cpp\r\n//\r\n// Desc: DirectShow sample code - implements an audio signal generator\r\n//       source filter.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\n// NB I don't know if directsource *can* actually work with VLC\r\n// I doub it\r\n//I.e. this particular sub-project fella prolly can't work as a VLC source\r\n#include <windows.h>\r\n#include <streams.h>\r\n#include <malloc.h>\r\n\r\n#include <math.h>\r\n#include <mmreg.h>\r\n#include <msacm.h>\r\n\r\n#include <initguid.h>\r\n#if (1100 > _MSC_VER)\r\n#include <olectlid.h>\r\n#else\r\n#include <olectl.h>\r\n#endif\r\n\r\n\r\n#define _AUDIOSYNTH_IMPLEMENTATION_\r\n\r\n#include \"DynSrc.h\"\r\n#include \"isynth.h\"\r\n#include \"synth.h\"\r\n#include \"synthprp.h\"\r\n#include <stdio.h>\r\n\r\n// setup data\r\n\r\nconst AMOVIESETUP_MEDIATYPE sudOpPinTypes =\r\n{ &MEDIATYPE_Audio      // clsMajorType\r\n, &MEDIASUBTYPE_NULL }; // clsMinorType\r\n\r\nconst AMOVIESETUP_PIN sudOpPin =\r\n{ L\"Output\"          // strName\r\n, FALSE              // bRendered\r\n, TRUE               // bOutput\r\n, FALSE              // bZero\r\n, FALSE              // bMany\r\n, &CLSID_NULL        // clsConnectsToFilter\r\n, L\"Input\"           // strConnectsToPin\r\n, 1                  // nTypes\r\n, &sudOpPinTypes };  // lpTypes\r\n\r\nconst AMOVIESETUP_FILTER sudSynth =\r\n{ &CLSID_SynthFilter     // clsID\r\n, L\"Audio Synthesizer\" // strName\r\n, MERIT_UNLIKELY       // dwMerit\r\n, 1                    // nPins\r\n, &sudOpPin };         // lpPin\r\n\r\n// -------------------------------------------------------------------------\r\n// g_Templates\r\n// -------------------------------------------------------------------------\r\n// COM global table of objects in this dll\r\n\r\nCFactoryTemplate g_Templates[] = {\r\n\r\n    { L\"Audio Synthesizer\"\r\n    , &CLSID_SynthFilter\r\n    , CSynthFilter::CreateInstance\r\n    , NULL\r\n    , &sudSynth }\r\n  ,\r\n    { L\"Audio Synthesizer Property Page\"\r\n    , &CLSID_SynthPropertyPage\r\n    , CSynthProperties::CreateInstance }\r\n\r\n};\r\nint g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);\r\n\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// CSynthFilter, the main filter object\r\n// -------------------------------------------------------------------------\r\n//\r\n// CreateInstance\r\n//\r\n// The only allowed way to create Synthesizers\r\n\r\nCUnknown * WINAPI CSynthFilter::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) \r\n{\r\n    ASSERT(phr);\r\n    \r\n    CUnknown *punk = new CSynthFilter(lpunk, phr);\r\n    if (punk == NULL) {\r\n        if (phr)\r\n            *phr = E_OUTOFMEMORY;\r\n    }\r\n\r\n    return punk;\r\n}\r\n\r\n\r\n//\r\n// CSynthFilter::Constructor\r\n//\r\n// initialise a CSynthStream object so that we have a pin.\r\n\r\nCSynthFilter::CSynthFilter(LPUNKNOWN lpunk, HRESULT *phr)\r\n    : CDynamicSource(NAME(\"Audio Synthesizer Filter\"),lpunk, CLSID_SynthFilter, phr)\r\n    , CPersistStream(lpunk, phr)\r\n{\r\n    m_paStreams = (CDynamicSourceStream **) new CSynthStream*[1];\r\n    if (m_paStreams == NULL) {\r\n        if (phr)\r\n            *phr = E_OUTOFMEMORY;\r\n        return;\r\n    }\r\n\r\n    m_paStreams[0] = new CSynthStream(phr, this, L\"Audio Synth Stream\");\r\n    if (m_paStreams[0] == NULL) {\r\n        if (phr)\r\n            *phr = E_OUTOFMEMORY;\r\n        return;\r\n    }\r\n\r\n    if (SUCCEEDED(*phr)) {\r\n        ASSERT(m_Synth);\r\n        m_Synth->put_SynthFormat(1,     // Channels\r\n                                 8,     // Bits Per Sample\r\n                                 11025  // Samples Per Sececond\r\n                                 );\r\n    }\r\n}\r\n\r\n\r\n\r\nSTDMETHODIMP CSynthFilter::GetClassID(CLSID *pClsid)\r\n{\r\n    return CBaseFilter::GetClassID(pClsid);\r\n}\r\n\r\n\r\nint CSynthFilter::SizeMax ()\r\n{\r\n    return sizeof (int) * 8;\r\n}\r\n\r\n\r\n\r\nDWORD CSynthFilter::GetSoftwareVersion(void)\r\n{\r\n    return 1;\r\n}\r\n\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// CSynthStream, the output pin\r\n// -------------------------------------------------------------------------\r\n\r\n//\r\n// CSynthStream::Constructor\r\n//\r\n\r\nCSynthStream::CSynthStream(HRESULT *phr, CSynthFilter *pParent, LPCWSTR pName)\r\n    : CDynamicSourceStream(NAME(\"Audio Synth output pin\"),phr, pParent, pName)\r\n    , m_hPCMToMSADPCMConversionStream(NULL)\r\n    , m_dwTempPCMBufferSize(0)\r\n    , m_fFirstSampleDelivered(FALSE)\r\n    , m_llSampleMediaTimeStart(0) \r\n{\r\n    ASSERT(phr);\r\n\r\n    m_Synth = new CAudioSynth(pParent->pStateLock());\r\n\r\n    pParent->m_Synth = m_Synth;\r\n    if (m_Synth == NULL) {\r\n        *phr = E_OUTOFMEMORY;\r\n        return;\r\n    }\r\n\r\n    m_pParent = pParent;\r\n}\r\n\r\n\r\n//\r\n// CSynthStream::Destructor\r\n//\r\nCSynthStream::~CSynthStream(void) \r\n{\r\n    delete m_Synth;\r\n}\r\n\r\n\r\nHRESULT LoopbackCapture(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize, WAVEFORMATEX* ifNotNullThenJustSetTypeOnly);\r\n\r\n\r\n//\r\n// FillBuffer\r\n//\r\n// Stuffs the buffer with data\r\n// \"they\" call this\r\n// then \"they\" call Deliver...so I guess we just fill it with something?\r\n// they *must* call this only every so often...\r\n// you probably should fill the entire buffer...hmm...\r\nHRESULT CSynthStream::FillBuffer(IMediaSample *pms) \r\n{\r\n    CheckPointer(pms,E_POINTER);\r\n\r\n    BYTE *pData;\r\n\r\n    HRESULT hr = pms->GetPointer(&pData);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    // This function must hold the state lock because it calls\r\n    // FillPCMAudioBuffer().\r\n    CAutoLock lStateLock(m_pParent->pStateLock());\r\n    \r\n    // This lock must be held because this function uses\r\n    // m_dwTempPCMBufferSize, m_hPCMToMSADPCMConversionStream,\r\n    // m_rtSampleTime, m_fFirstSampleDelivered and\r\n    // m_llSampleMediaTimeStart.\r\n    CAutoLock lShared(&m_cSharedState);\r\n\r\n    WAVEFORMATEX* pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();\r\n\r\n    if (WAVE_FORMAT_PCM == pwfexCurrent->wFormatTag) \r\n    {\r\n        // old way\r\n\t\t// m_Synth->FillPCMAudioBuffer();\r\n\r\n\t\t// new way\r\n\t\tLoopbackCapture(*pwfexCurrent, pData, pms->GetSize(), NULL);\r\n\r\n        hr = pms->SetActualDataLength(pms->GetSize());\r\n        if (FAILED(hr))\r\n            return hr;\r\n\r\n    }\r\n    else \r\n    {\r\n\t\t// who cares about ADPCM...\r\n\t\treturn E_FAIL;\r\n    }\r\n\r\n    // Set the sample's start and end time stamps...\r\n    CRefTime rtStart = m_rtSampleTime;\r\n\r\n    m_rtSampleTime = rtStart + (REFERENCE_TIME)(UNITS * pms->GetActualDataLength()) / \r\n                     (REFERENCE_TIME)pwfexCurrent->nAvgBytesPerSec;\r\n\r\n    hr = pms->SetTime((REFERENCE_TIME*)&rtStart, (REFERENCE_TIME*)&m_rtSampleTime);\r\n\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    // Set the sample's properties.\r\n    hr = pms->SetPreroll(FALSE);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n\t//...CDynamicSourceStream::SetMediaType(\r\n    hr = pms->SetMediaType(NULL);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n   \r\n    hr = pms->SetDiscontinuity(!m_fFirstSampleDelivered);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n    \r\n    hr = pms->SetSyncPoint(!m_fFirstSampleDelivered);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    LONGLONG llMediaTimeStart = m_llSampleMediaTimeStart;\r\n    \r\n    DWORD dwNumAudioSamplesInPacket = (pms->GetActualDataLength() * BITS_PER_BYTE) /\r\n                                      (pwfexCurrent->nChannels * pwfexCurrent->wBitsPerSample);\r\n\r\n    LONGLONG llMediaTimeStop = m_llSampleMediaTimeStart + dwNumAudioSamplesInPacket;\r\n\r\n    hr = pms->SetMediaTime(&llMediaTimeStart, &llMediaTimeStop);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    m_llSampleMediaTimeStart = llMediaTimeStop;\r\n    m_fFirstSampleDelivered = TRUE;\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// Format Support\r\n//\r\n\r\n//\r\n// GetMediaType\r\n// I believe \"they\" call this...\r\n// we only have one type at a time...\r\n// so we just return our one type...\r\n// which we already told them what it was.\r\nHRESULT CSynthStream::GetMediaType(CMediaType *pmt) \r\n{\r\n    CheckPointer(pmt,E_POINTER);\r\n\r\n    // The caller must hold the state lock because this function\r\n    // calls get_OutputFormat() and GetPCMFormatStructure().\r\n    // The function assumes that the state of the m_Synth\r\n    // object does not change between the two calls.  The\r\n    // m_Synth object's state will not change if the \r\n    // state lock is held.\r\n    ASSERT(CritCheckIn(m_pParent->pStateLock()));\r\n\r\n\treturn setAsNormal(pmt);\t\r\n}\r\n\r\n#define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr);\r\n\r\n\r\nHRESULT CSynthStream::setAsNormal(CMediaType *pmt) {\r\n\t    WAVEFORMATEX *pwfex;\r\n    SYNTH_OUTPUT_FORMAT ofCurrent;\r\n\r\n    HRESULT hr = m_Synth->get_OutputFormat( &ofCurrent ); // get PCM\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n    \r\n    if(SYNTH_OF_PCM == ofCurrent)\r\n    {\r\n\t\t// we always get here...\r\n        pwfex = (WAVEFORMATEX *) pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));\r\n        if(NULL == pwfex)\r\n        {\r\n            return E_OUTOFMEMORY;\r\n        }\r\n\r\n\t\t// we'll set it as PCM or what not, within this call...\r\n\r\n\t\t// now tell them \"this is what we will give you...\"\r\n\t\tWAVEFORMATEX unused;\r\n\t\tLoopbackCapture(unused, NULL, -1, pwfex);\r\n        \r\n\t\t// old sin wave way...\r\n\t\t//m_Synth->GetPCMFormatStructure(pwfex);\r\n\r\n    }\r\n    else if(SYNTH_OF_MS_ADPCM == ofCurrent)\r\n    {\r\n\t\t  // !no ADPCM!\r\n\t\t  return E_FAIL;\r\n    }\r\n    else\r\n    {\r\n        return E_UNEXPECTED;\r\n    }\r\n\r\n    return CreateAudioMediaType(pwfex, pmt, FALSE); // not ours...\r\n\r\n}\r\n\r\n// other fella doesn't even have this one...\r\n// maybe it could if it wanted to...\r\nHRESULT CSynthStream::CompleteConnect(IPin *pReceivePin)\r\n{\r\n    // This lock must be held because this function uses\r\n    // m_hPCMToMSADPCMConversionStream, m_fFirstSampleDelivered \r\n    // and m_llSampleMediaTimeStart.\r\n    CAutoLock lShared(&m_cSharedState);\r\n\r\n    HRESULT hr;\r\n    WAVEFORMATEX *pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();\r\n\r\n    if(WAVE_FORMAT_PCM == pwfexCurrent->wFormatTag)\r\n    {\r\n\t\t// always create our pretty sin wave on connect...\r\n        hr = m_Synth->AllocWaveCache(*pwfexCurrent);\r\n        if(FAILED(hr))\r\n        {\r\n            return hr;\r\n        }\r\n    }\r\n    else if(WAVE_FORMAT_ADPCM == pwfexCurrent->wFormatTag)\r\n    {\r\n\t\t// no ADPCM!\r\n\t\treturn E_FAIL;\r\n    }\r\n    else\r\n    {\r\n        ASSERT(NULL == m_hPCMToMSADPCMConversionStream);\r\n    }\r\n\r\n    hr = CDynamicSourceStream::CompleteConnect(pReceivePin);\r\n    if(FAILED(hr))\r\n    {\r\n        if(WAVE_FORMAT_ADPCM == pwfexCurrent->wFormatTag)\r\n        {\r\n            // acmStreamClose() should never fail because m_hPCMToMSADPCMConversionStream\r\n            // holds a valid ACM stream handle and all operations using the handle are \r\n            // synchronous.\r\n            EXECUTE_ASSERT(0 == acmStreamClose(m_hPCMToMSADPCMConversionStream, 0));\r\n            m_hPCMToMSADPCMConversionStream = NULL;\r\n        }\r\n\r\n        return hr;\r\n    }\r\n\r\n    m_fFirstSampleDelivered = FALSE;\r\n    m_llSampleMediaTimeStart = 0;\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n// pin connect was broken\r\nHRESULT CSynthStream::BreakConnect(void)\r\n{\r\n    // This lock must be held because this function uses\r\n    // m_hPCMToMSADPCMConversionStream and m_dwTempPCMBufferSize.\r\n    CAutoLock lShared(&m_cSharedState);\r\n\r\n    HRESULT hr = CDynamicSourceStream::BreakConnect();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    if(NULL != m_hPCMToMSADPCMConversionStream)\r\n    {\r\n        // acmStreamClose() should never fail because m_hPCMToMSADPCMConversionStream\r\n        // holds a valid ACM stream handle and all operations using the handle are \r\n        // synchronous.\r\n        EXECUTE_ASSERT(0 == acmStreamClose(m_hPCMToMSADPCMConversionStream, 0));\r\n        m_hPCMToMSADPCMConversionStream = NULL;\r\n        m_dwTempPCMBufferSize = 0;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n//\r\n// DecideBufferSize\r\n//\r\n// This will always be called after the format has been sucessfully\r\n// negotiated. So we have a look at m_mt to see what format we agreed to.\r\n// Then we can ask for buffers of the correct size to contain them.\r\nHRESULT CSynthStream::DecideBufferSize(IMemAllocator *pAlloc,\r\n                                       ALLOCATOR_PROPERTIES *pProperties)\r\n{\r\n    // The caller should always hold the shared state lock \r\n    // before calling this function.  This function must hold \r\n    // the shared state lock because it uses m_hPCMToMSADPCMConversionStream\r\n    // m_dwTempPCMBufferSize.\r\n    ASSERT(CritCheckIn(&m_cSharedState));\r\n\r\n    CheckPointer(pAlloc,E_POINTER);\r\n    CheckPointer(pProperties,E_POINTER);\r\n\r\n    WAVEFORMATEX *pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();\r\n\r\n    if(WAVE_FORMAT_PCM == pwfexCurrent->wFormatTag)\r\n    {\r\n        pProperties->cbBuffer = WaveBufferSize; // guess 16K is standard for PCM? what?\r\n    }\r\n    else\r\n    {\r\n\t\t// no ADMCP!\r\n        return E_FAIL;        \r\n    }\r\n\r\n    int nBitsPerSample = pwfexCurrent->wBitsPerSample;\r\n    int nSamplesPerSec = pwfexCurrent->nSamplesPerSec;\r\n    int nChannels = pwfexCurrent->nChannels;\r\n\r\n\t// Get 1 second worth of buffers\r\n\r\n    pProperties->cBuffers = (nChannels * nSamplesPerSec * nBitsPerSample) / \r\n                            (pProperties->cbBuffer * BITS_PER_BYTE);\r\n\r\n    // Get 1/2 second worth of buffers\r\n    pProperties->cBuffers /= 2;\r\n    if(pProperties->cBuffers < 1)\r\n        pProperties->cBuffers = 1 ;\r\n\r\n    // Ask the allocator to reserve us the memory...\r\n\r\n    ALLOCATOR_PROPERTIES Actual;\r\n    HRESULT hr = pAlloc->SetProperties(pProperties,&Actual);\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    // Is this allocator unsuitable\r\n\r\n    if(Actual.cbBuffer < pProperties->cbBuffer)\r\n    {\r\n        return E_FAIL;\r\n    }\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n    // switch the pin to active (paused or running) mode\r\n    // not an error to call this if already active\r\n//\r\n// Active\r\n//\r\nHRESULT CSynthStream::Active(void)\r\n{\r\n    // This lock must be held because the function\r\n    // uses m_rtSampleTime, m_fFirstSampleDelivered\r\n    // and m_llSampleMediaTimeStart.\r\n    CAutoLock lShared(&m_cSharedState);\r\n\r\n    HRESULT hr = CDynamicSourceStream::Active();\r\n    if(FAILED(hr))\r\n    {\r\n        return hr;\r\n    }\r\n\r\n    m_rtSampleTime = 0;\r\n    m_fFirstSampleDelivered = FALSE;\r\n    m_llSampleMediaTimeStart = 0;\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// CAudioSynth\r\n// -------------------------------------------------------------------------\r\n// Object that knows nothing about DirectShow, but just synthesizes waveforms\r\n\r\nCAudioSynth::CAudioSynth(\r\n                CCritSec* pStateLock,\r\n                int Frequency,\r\n                int Waveform,\r\n                int iBitsPerSample,\r\n                int iChannels,\r\n                int iSamplesPerSec,\r\n                int iAmplitude\r\n                )\r\n    : m_bWaveCache(NULL)\r\n    , m_wWaveCache(NULL)\r\n    , m_pStateLock(pStateLock)\r\n{\r\n    ASSERT(Waveform >= WAVE_SINE);\r\n    ASSERT(Waveform <  WAVE_LAST);\r\n\r\n    m_iFrequency = Frequency;\r\n    m_iWaveform = Waveform;\r\n    m_iAmplitude = iAmplitude;\r\n    m_iSweepStart = DefaultSweepStart;\r\n    m_iSweepEnd = DefaultSweepEnd;\r\n\r\n    m_wFormatTag = WAVE_FORMAT_PCM;\r\n    m_wBitsPerSample = (WORD) iBitsPerSample;\r\n    m_wChannels = (WORD) iChannels;\r\n    m_dwSamplesPerSec = iSamplesPerSec;\r\n}\r\n\r\n\r\nCAudioSynth::~CAudioSynth()\r\n{\r\n    if(m_bWaveCache)\r\n    {\r\n        delete[] m_bWaveCache;\r\n    }\r\n\r\n    if(m_wWaveCache)\r\n    {\r\n        delete[] m_wWaveCache;\r\n    }\r\n}\r\n\r\n\r\n//\r\n// AllocWaveCache\r\n//\r\n//\r\nHRESULT CAudioSynth::AllocWaveCache(const WAVEFORMATEX& wfex)\r\n{\r\n    // The caller should hold the state lock because this\r\n    // function uses m_iWaveCacheCycles, m_iWaveCacheSize\r\n    // m_iFrequency, m_bWaveCache and m_wWaveCache.  The\r\n    // function should also hold the state lock because\r\n    // it calls CalcCache().\r\n    ASSERT(CritCheckIn(m_pStateLock));\r\n\r\n    m_iWaveCacheCycles = m_iFrequency;\r\n    m_iWaveCacheSize = (int) wfex.nSamplesPerSec;\r\n\r\n    if(m_bWaveCache)\r\n    {\r\n        delete[] m_bWaveCache;\r\n        m_bWaveCache = NULL;\r\n    }\r\n    if(m_wWaveCache)\r\n    {\r\n        delete[] m_wWaveCache;\r\n        m_wWaveCache = NULL;\r\n    }\r\n\r\n    // The wave cache always stores PCM audio data.\r\n    if(wfex.wBitsPerSample == 8)\r\n    {\r\n        m_bWaveCache = new BYTE [m_iWaveCacheSize];\r\n        if(NULL == m_bWaveCache)\r\n        {\r\n            return E_OUTOFMEMORY;\r\n        }\r\n    }\r\n    else\r\n    {\r\n        m_wWaveCache = new WORD [m_iWaveCacheSize];\r\n        if(NULL == m_wWaveCache)\r\n        {\r\n            return E_OUTOFMEMORY;\r\n        }\r\n    }\r\n\r\n    CalcCache(wfex); // fill it with a sin wave...\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n// I don't think this is ever called anymore...\r\n\r\nvoid CAudioSynth::GetPCMFormatStructure(WAVEFORMATEX* pwfex)\r\n{\r\n    ASSERT(pwfex);\r\n\r\n    // The caller must hold the state lock because this function uses\r\n    // m_wChannels, m_wBitsPerSample and m_dwSamplesPerSec.\r\n    ASSERT(CritCheckIn(m_pStateLock));\r\n\r\n    // Check for valid input parametes.\r\n    ASSERT((1 == m_wChannels) || (2 == m_wChannels));\r\n    ASSERT((8 == m_wBitsPerSample) || (16 == m_wBitsPerSample));\r\n    ASSERT((8000 == m_dwSamplesPerSec) || (11025 == m_dwSamplesPerSec) ||\r\n        (22050 == m_dwSamplesPerSec) || (44100 == m_dwSamplesPerSec));\r\n\r\n    pwfex->wFormatTag = WAVE_FORMAT_PCM;\r\n    pwfex->nChannels = m_wChannels;\r\n    pwfex->nSamplesPerSec = m_dwSamplesPerSec;\r\n    pwfex->wBitsPerSample = m_wBitsPerSample;        \r\n    pwfex->nBlockAlign = (WORD)((pwfex->wBitsPerSample * pwfex->nChannels) / BITS_PER_BYTE);\r\n    pwfex->nAvgBytesPerSec = pwfex->nBlockAlign * pwfex->nSamplesPerSec;\r\n    pwfex->cbSize = 0;\r\n\r\n\t// NPE here, too?\r\n\r\n\tFILE *fp = fopen(\"/normal is\", \"w\");\r\n\r\n\tfprintf(fp, \"hello world %d %d %d %d %d %d %d\", pwfex->wFormatTag, pwfex->nChannels, \r\n\t\tpwfex->nSamplesPerSec, pwfex->wBitsPerSample, pwfex->nBlockAlign, pwfex->nAvgBytesPerSec, pwfex->cbSize );\r\n\tfclose(fp);\r\n\r\n}\r\n\r\n\r\n\r\nvoid CAudioSynth::copyCacheToOutputBuffers(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize)\r\n{\r\n\tif(wfex.wBitsPerSample == 8 && wfex.nChannels == 1)\r\n    {\r\n        while(iSize--)\r\n        {\r\n            *pBuf++ = m_bWaveCache[m_iWaveCacheIndex++];\r\n            if(m_iWaveCacheIndex >= m_iWaveCacheSize)\r\n                m_iWaveCacheIndex = 0;\r\n        }\r\n    }\r\n    else if(wfex.wBitsPerSample == 8 && wfex.nChannels == 2)\r\n    {\r\n        iSize /= 2;\r\n\r\n        while(iSize--)\r\n        {\r\n            *pBuf++ = m_bWaveCache[m_iWaveCacheIndex];\r\n            *pBuf++ = m_bWaveCache[m_iWaveCacheIndex++];\r\n            if(m_iWaveCacheIndex >= m_iWaveCacheSize)\r\n                m_iWaveCacheIndex = 0;\r\n        }\r\n    }\r\n    else if(wfex.wBitsPerSample == 16 && wfex.nChannels == 1)\r\n    {\r\n        WORD * pW = (WORD *) pBuf;\r\n        iSize /= 2;\r\n\r\n        while(iSize--)\r\n        {\r\n            *pW++ = m_wWaveCache[m_iWaveCacheIndex++];\r\n            if(m_iWaveCacheIndex >= m_iWaveCacheSize)\r\n                m_iWaveCacheIndex = 0;\r\n        }\r\n    }\r\n    else if(wfex.wBitsPerSample == 16 && wfex.nChannels == 2)\r\n    {\r\n        WORD * pW = (WORD *) pBuf;\r\n        iSize /= 4;\r\n\r\n        while(iSize--)\r\n        {\r\n            *pW++ = m_wWaveCache[m_iWaveCacheIndex];\r\n            *pW++ = m_wWaveCache[m_iWaveCacheIndex++];\r\n            if(m_iWaveCacheIndex >= m_iWaveCacheSize)\r\n                m_iWaveCacheIndex = 0;\r\n        }\r\n    }\r\n}\r\n\r\n\r\n// copied from \r\n\r\nSTDAPI AMovieSetupRegisterServer( CLSID   clsServer, LPCWSTR szDescription, LPCWSTR szFileName, LPCWSTR szThreadingModel = L\"Both\", LPCWSTR szServerType     = L\"InprocServer32\" );\r\nSTDAPI AMovieSetupUnregisterServer( CLSID clsServer );\r\n#define CreateComObject(clsid, iid, var) CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&var);\r\n\r\n\r\n// straight call to here on init, instead of to\r\n// AMovieDllRegisterServer2 which is what the other fella does...\r\n// which I assume is similar to this...maybe?\r\nSTDAPI RegisterFilters( BOOL bRegister )\r\n{\r\n    HRESULT hr = NOERROR;\r\n    WCHAR achFileName[MAX_PATH];\r\n    char achTemp[MAX_PATH];\r\n    ASSERT(g_hInst != 0);\r\n\r\n    if( 0 == GetModuleFileNameA(g_hInst, achTemp, sizeof(achTemp))) \r\n        return AmHresultFromWin32(GetLastError());\r\n\r\n    MultiByteToWideChar(CP_ACP, 0L, achTemp, lstrlenA(achTemp) + 1, \r\n                       achFileName, NUMELMS(achFileName));\r\n  \r\n    hr = CoInitialize(0);\r\n    if(bRegister)\r\n    {\r\n        hr = AMovieSetupRegisterServer(CLSID_SynthFilter, L\"Audio Synthesizer\", achFileName, L\"Both\", L\"InprocServer32\");\r\n    }\r\n\r\n    if( SUCCEEDED(hr) )\r\n    {\r\n        IFilterMapper2 *fm = 0;\r\n        hr = CreateComObject( CLSID_FilterMapper2, IID_IFilterMapper2, fm );\r\n        if( SUCCEEDED(hr) )\r\n        {\r\n            if(bRegister)\r\n            {\r\n                IMoniker *pMoniker = 0;\r\n                REGFILTER2 rf2;\r\n                rf2.dwVersion = 1;\r\n                rf2.dwMerit = MERIT_DO_NOT_USE;\r\n                rf2.cPins = 1;\r\n                rf2.rgPins = &sudOpPin;\r\n                hr = fm->RegisterFilter(CLSID_SynthFilter, L\"Audio Synthesizer\", &pMoniker, &CLSID_AudioInputDeviceCategory, NULL, &rf2);\r\n            }\r\n            else\r\n            {\r\n                hr = fm->UnregisterFilter(&CLSID_AudioInputDeviceCategory, 0, CLSID_SynthFilter);\r\n            }\r\n        }\r\n\r\n      // release interface\r\n      //\r\n      if(fm)\r\n          fm->Release();\r\n    }\r\n\r\n    if( SUCCEEDED(hr) && !bRegister )\r\n        hr = AMovieSetupUnregisterServer( CLSID_SynthFilter );\r\n\r\n    CoFreeUnusedLibraries();\r\n    CoUninitialize();\r\n    return hr;\r\n}\r\n\r\n\r\n////////////////////////////////////////////////////////////////////////\r\n//\r\n// Exported entry points for registration and unregistration \r\n// (in this case they only call through to default implementations).\r\n//\r\n////////////////////////////////////////////////////////////////////////\r\n\r\n\r\nSTDAPI DllRegisterServer()\r\n{\r\n\t//printf(\"hello there\");\r\n    return RegisterFilters(TRUE);\r\n}\r\n\r\nSTDAPI  DllUnregisterServer()\r\n{\r\n    return RegisterFilters(FALSE);\r\n}\r\n\r\n//\r\n// DllEntryPoint\r\n//\r\nextern \"C\" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);\r\n\r\nBOOL APIENTRY DllMain(HANDLE hModule, \r\n                      DWORD  dwReason, \r\n                      LPVOID lpReserved)\r\n{\r\n\treturn DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);\r\n}\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.def",
    "content": ";===========================================================================\r\n;  Copyright (c) 1992-2002  Microsoft Corporation.  All Rights Reserved.\r\n;===========================================================================\r\n\r\nLIBRARY     Synth.dll\r\n\r\nEXPORTS\r\n            DllMain                 PRIVATE\r\n            DllGetClassObject       PRIVATE\r\n            DllCanUnloadNow         PRIVATE\r\n            DllRegisterServer       PRIVATE\r\n            DllUnregisterServer     PRIVATE\r\n\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.h",
    "content": "//------------------------------------------------------------------------------\r\n// File: Synth.h\r\n//\r\n// Desc: DirectShow sample code - header file for audio signal generator \r\n//       source filter.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\n#ifndef __AUDIOSYNTH__\r\n#define __AUDIOSYNTH__\r\n\r\n// There are 8 bits in a byte.\r\nconst DWORD BITS_PER_BYTE = 8;\r\n\r\n//CLSID_SynthFilter\r\n//{79A98DE0-BC00-11ce-AC2E-444553540000}\r\nDEFINE_GUID(CLSID_SynthFilter,\r\n0x79a98de0, 0xbc00, 0x11ce, 0xac, 0x2e, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);\r\n\r\n//CLSID_SynthFilterPropertyPage\r\n//{79A98DE1-BC00-11ce-AC2E-444553540000}\r\nDEFINE_GUID(CLSID_SynthPropertyPage,\r\n0x79a98de1, 0xbc00, 0x11ce, 0xac, 0x2e, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);\r\n\r\nconst double TWOPI = 6.283185308;\r\nconst int MaxFrequency = 20000;\r\nconst int MinFrequency = 0;\r\nconst int DefaultFrequency = 440;       // A-440\r\nconst int MaxAmplitude = 100;\r\nconst int MinAmplitude = 0;\r\nconst int DefaultSweepStart = DefaultFrequency;\r\nconst int DefaultSweepEnd = 5000;\r\nconst int WaveBufferSize = 16*1024;     // Size of each allocated buffer\r\n                                        // Originally used to be 2K, but at\r\n                                        // 44khz/16bit/stereo you would get\r\n                                        // audio breaks with a transform in the\r\n                                        // middle.\r\n\r\n// huh?\r\n\r\nenum Waveforms {\r\n    WAVE_SINE = 0,\r\n    WAVE_SQUARE,\r\n    WAVE_SAWTOOTH,\r\n    WAVE_SINESWEEP,\r\n    WAVE_LAST           // Always keep this entry last\r\n};\r\n\r\n#define WM_PROPERTYPAGE_ENABLE  (WM_USER + 100)\r\n\r\n// below stuff is implementation-only....\r\n#ifdef _AUDIOSYNTH_IMPLEMENTATION_\r\n\r\nclass CSynthStream;\r\n\r\n// -------------------------------------------------------------------------\r\n// CAudioSynth\r\n// -------------------------------------------------------------------------\r\n\r\nclass CAudioSynth {\r\n\r\npublic:\r\n\r\n    CAudioSynth(\r\n                CCritSec* pStateLock,\r\n                int Frequency = DefaultFrequency,\r\n                int Waveform = WAVE_SINE,\r\n                int iBitsPerSample = 8,\r\n                int iChannels = 1,\r\n                int iSamplesPerSec = 11025,\r\n                int iAmplitude = 100\r\n                );\r\n\r\n    ~CAudioSynth();\r\n\r\n    // Load the buffer with the current waveform\r\n    void FillPCMAudioBuffer(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize);\r\n\t// helper for same\r\n\tvoid copyCacheToOutputBuffers(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize);\r\n\r\n    // Set the \"current\" format and allocate temporary memory\r\n    HRESULT AllocWaveCache(const WAVEFORMATEX& wfex);\r\n\r\n    void GetPCMFormatStructure(WAVEFORMATEX* pwfex);\r\n\r\n    STDMETHODIMP get_Frequency(int *Frequency);\r\n    STDMETHODIMP put_Frequency(int  Frequency);\r\n    STDMETHODIMP get_Waveform(int *Waveform);\r\n    STDMETHODIMP put_Waveform(int  Waveform);\r\n    STDMETHODIMP get_Channels(int *Channels);\r\n    STDMETHODIMP put_Channels(int Channels);\r\n    STDMETHODIMP get_BitsPerSample(int *BitsPerSample);\r\n    STDMETHODIMP put_BitsPerSample(int BitsPerSample);\r\n    STDMETHODIMP get_SamplesPerSec(int *SamplesPerSec);\r\n    STDMETHODIMP put_SamplesPerSec(int SamplesPerSec);\r\n    STDMETHODIMP put_SynthFormat(int Channels, int BitsPerSample, int SamplesPerSec);\r\n    STDMETHODIMP get_Amplitude(int *Amplitude);\r\n    STDMETHODIMP put_Amplitude(int  Amplitude);\r\n    STDMETHODIMP get_SweepRange(int *SweepStart, int *SweepEnd);\r\n    STDMETHODIMP put_SweepRange(int  SweepStart, int  SweepEnd);\r\n    STDMETHODIMP get_OutputFormat(SYNTH_OUTPUT_FORMAT *pOutputFormat);\r\n    STDMETHODIMP put_OutputFormat(SYNTH_OUTPUT_FORMAT ofOutputFormat);\r\n\r\nprivate:\r\n    CCritSec* m_pStateLock;\r\n\r\n    WORD  m_wChannels;          // The output format's current number of channels.\r\n    WORD  m_wFormatTag;         // The output format.  This can be PCM audio or MS ADPCM audio.\r\n    DWORD m_dwSamplesPerSec;    // The number of samples produced in one second by the synth filter.\r\n    WORD  m_wBitsPerSample;     // The number of bits in each sample.  This member is only valid if the\r\n                                // current format is PCM audio.\r\n\r\n    int m_iWaveform;            // WAVE_SINE ...\r\n    int m_iFrequency;           // if not using sweep, this is the frequency\r\n    int m_iAmplitude;           // 0 to 100\r\n\r\n    int m_iWaveformLast;        // keep track of the last known format\r\n    int m_iFrequencyLast;       // so we can flush the cache if necessary\r\n    int m_iAmplitudeLast;\r\n    int m_iCurrentSample;       // 0 to iSamplesPerSec-1\r\n\r\n    BYTE * m_bWaveCache;        // Wave Cache as BYTEs.  This cache ALWAYS holds PCM audio data.\r\n    WORD * m_wWaveCache;        // Wave Cache as WORDs.  This cache ALWAYS holds PCM audio data.\r\n\r\n    int m_iWaveCacheSize;       // how big is the cache?\r\n    int m_iWaveCacheCycles;     // how many cycles are in the cache\r\n    int m_iWaveCacheIndex;\r\n\r\n    int m_iSweepStart;           // start of sweep\r\n    int m_iSweepEnd;             // end of sweep\r\n\r\n    void CalcCache         (const WAVEFORMATEX& wfex);\r\n    void CalcCacheSine     (const WAVEFORMATEX& wfex);\r\n    void CalcCacheSquare   (const WAVEFORMATEX& wfex);\r\n    void CalcCacheSawtooth (const WAVEFORMATEX& wfex);\r\n    void CalcCacheSweep    (const WAVEFORMATEX& wfex);\r\n\r\n};\r\n\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// CSynthFilter\r\n// -------------------------------------------------------------------------\r\n// CSynthFilter manages filter level stuff\r\n\r\nclass CSynthFilter :    public ISynth2,\r\n                        public CPersistStream,\r\n                        public ISpecifyPropertyPages,\r\n                        public CDynamicSource {\r\n\r\npublic:\r\n\r\n    static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);\r\n    ~CSynthFilter();\r\n\r\n    DECLARE_IUNKNOWN;\r\n\r\n    // override this to reveal our property interface\r\n    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);\r\n\r\n    // --- ISpecifyPropertyPages ---\r\n\r\n    // return our property pages\r\n    STDMETHODIMP GetPages(CAUUID * pPages);\r\n\r\n    // --- IPersistStream Interface\r\n\r\n    STDMETHODIMP GetClassID(CLSID *pClsid);\r\n    int SizeMax();\r\n    HRESULT WriteToStream(IStream *pStream);\r\n    HRESULT ReadFromStream(IStream *pStream);\r\n    DWORD GetSoftwareVersion(void);\r\n\r\n    //\r\n    // --- ISynth2 ---\r\n    //\r\n\r\n    STDMETHODIMP get_Frequency(int *Frequency);\r\n    STDMETHODIMP put_Frequency(int Frequency);\r\n    STDMETHODIMP get_Waveform(int *Waveform);\r\n    STDMETHODIMP put_Waveform(int Waveform);\r\n    STDMETHODIMP get_Channels(int *Channels);\r\n    STDMETHODIMP get_BitsPerSample(int *BitsPerSample);\r\n    STDMETHODIMP get_SamplesPerSec(int *SamplesPerSec);\r\n    STDMETHODIMP put_Channels(int Channels);\r\n    STDMETHODIMP put_BitsPerSample(int BitsPersample);\r\n    STDMETHODIMP put_SamplesPerSec(int SamplesPerSec);\r\n    STDMETHODIMP get_Amplitude(int *Amplitude);\r\n    STDMETHODIMP put_Amplitude(int Amplitude);\r\n    STDMETHODIMP get_SweepRange(int *SweepStart, int *SweepEnd);\r\n    STDMETHODIMP put_SweepRange(int  SweepStart, int  SweepEnd);\r\n    STDMETHODIMP get_OutputFormat(SYNTH_OUTPUT_FORMAT *pOutputFormat);\r\n    STDMETHODIMP put_OutputFormat(SYNTH_OUTPUT_FORMAT ofOutputFormat);\r\n\r\n    CAudioSynth *m_Synth;           // the current synthesizer\r\n\r\nprivate:\r\n\r\n    // it is only allowed to to create these objects with CreateInstance\r\n    CSynthFilter(LPUNKNOWN lpunk, HRESULT *phr);\r\n\r\n    // When the format changes, reconnect...\r\n    void ReconnectWithNewFormat(void);\r\n\r\n};\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// CSynthStream\r\n// -------------------------------------------------------------------------\r\n// CSynthStream manages the data flow from the output pin.\r\n\r\nclass CSynthStream : public CDynamicSourceStream {\r\n\r\npublic:\r\n\r\n    CSynthStream(HRESULT *phr, CSynthFilter *pParent, LPCWSTR pPinName);\r\n    ~CSynthStream();\r\n\r\n    BOOL ReadyToStop(void) {return FALSE;}\r\n\r\n    // stuff an audio buffer with the current format\r\n    HRESULT FillBuffer(IMediaSample *pms);\r\n\r\n    // ask for buffers of the size appropriate to the agreed media type.\r\n    HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc,\r\n                             ALLOCATOR_PROPERTIES *pProperties);\r\n\r\n    HRESULT GetMediaType(CMediaType *pmt);\r\n\tHRESULT setAsNormal(CMediaType *pmt);\r\n\r\n    HRESULT CompleteConnect(IPin *pReceivePin);\r\n    HRESULT BreakConnect(void);\r\n\r\n    // resets the stream time to zero.\r\n    HRESULT Active(void);\r\n\r\nprivate:\r\n\r\n    void DerivePCMFormatFromADPCMFormatStructure(const WAVEFORMATEX& wfexADPCM, WAVEFORMATEX* pwfexPCM);\r\n\r\n    // Access to this state information should be serialized with the filters\r\n    // critical section (m_pFilter->pStateLock())\r\n\r\n    // This lock protects: m_dwTempPCMBufferSize, m_hPCMToMSADPCMConversionStream,\r\n    // m_rtSampleTime, m_fFirstSampleDelivered and m_llSampleMediaTimeStart\r\n    CCritSec    m_cSharedState;     \r\n\r\n    CRefTime     m_rtSampleTime;    // The time to be stamped on each sample\r\n    HACMSTREAM m_hPCMToMSADPCMConversionStream;\r\n\r\n    DWORD m_dwTempPCMBufferSize;\r\n    bool m_fFirstSampleDelivered;\r\n    LONGLONG m_llSampleMediaTimeStart;\r\n\r\n    CAudioSynth  *m_Synth;          // the current synthesizer\r\n    CSynthFilter *m_pParent;\r\n};\r\n\r\n#endif // _AUDIOSYNTH_IMPLEMENTATION_ implementation only....\r\n\r\n#endif /* __AUDIOSYNTH__ */\r\n\r\n\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.rc",
    "content": "//==========================================================================;\r\n//\r\n//  THIS CODE AND INFORMATION IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY\r\n//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\r\n//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR\r\n//  PURPOSE.\r\n//\r\n//  Copyright (c)  Microsoft Corporation.  All Rights Reserved.\r\n//\r\n//==========================================================================;\r\n//\r\n//Microsoft Visual C++ generated resource script.\r\n//\r\n\r\n#include <winresrc.h>\r\n#include \"resource.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 2 resource.\r\n//\r\n#include <windows.h>\r\n#include <commctrl.h>\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#undef APSTUDIO_READONLY_SYMBOLS\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// TEXTINCLUDE\r\n//\r\n\r\n1 TEXTINCLUDE DISCARDABLE \r\nBEGIN\r\n    \"resource.h\\0\"\r\nEND\r\n\r\n2 TEXTINCLUDE DISCARDABLE \r\nBEGIN\r\n    \"#include <windows.h>\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n3 TEXTINCLUDE DISCARDABLE \r\nBEGIN\r\n    \"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Dialog\r\n//\r\n\r\nIDD_SYNTHPROP1 DIALOG DISCARDABLE  0, 0, 316, 98\r\nSTYLE WS_CHILD\r\nFONT 8, \"MS Shell Dlg\"\r\nBEGIN\r\n    CONTROL         \"Generic1\",IDC_FREQTRACKBAR,\"msctls_trackbar32\",\r\n                    WS_TABSTOP | WS_CHILD | TBS_AUTOTICKS | TBS_VERT | TBS_RIGHT | TBS_ENABLESELRANGE,65,15,15,55\r\n    GROUPBOX        \"Frequency\",IDC_FREQUENCYGROUP,57,5,39,85,WS_GROUP\r\n    GROUPBOX        \"Waveform\",IDC_WAVEFORMGROUP,4,4,50,85,WS_GROUP\r\n    CONTROL         \"&Sine\",IDC_WAVESINE,\"Button\",BS_AUTORADIOBUTTON,8,20,40,\r\n                    10\r\n    CONTROL         \"Squar&e\",IDC_WAVESQUARE,\"Button\",BS_AUTORADIOBUTTON,8,\r\n                    35,41,10\r\n    CONTROL         \"Sa&wtooth\",IDC_WAVESAWTOOTH,\"Button\",BS_AUTORADIOBUTTON,\r\n                    8,50,44,10\r\n    CONTROL         \"Swee&p\",IDC_WAVESWEEP,\"Button\",BS_AUTORADIOBUTTON,\r\n                    8,65,41,10\r\n    GROUPBOX        \"Channels\",IDC_CHANNELSGROUP,145,5,75,25,WS_GROUP\r\n    CONTROL         \"&1\",IDC_CHANNELS1,\"Button\",BS_AUTORADIOBUTTON,147,15,20,\r\n                    10\r\n    CONTROL         \"&2\",IDC_CHANNELS2,\"Button\",BS_AUTORADIOBUTTON,171,15,20,\r\n                    10\r\n    GROUPBOX        \"Bits per sample\",IDC_BITSPERSAMPLEGROUP,145,36,75,24,\r\n                    WS_GROUP\r\n    CONTROL         \"&8\",IDC_BITSPERSAMPLE8,\"Button\",BS_AUTORADIOBUTTON,147,\r\n                    45,20,10\r\n    CONTROL         \"1&6\",IDC_BITSPERSAMPLE16,\"Button\",BS_AUTORADIOBUTTON,\r\n                    171,45,20,10\r\n    GROUPBOX        \"Sampling frequency\",IDC_SAMPLINGFREQUENCYGROUP,145,65,\r\n                    75,25,WS_GROUP\r\n    CONTROL         \"&11\",IDC_SAMPLINGFREQ11,\"Button\",BS_AUTORADIOBUTTON,147,\r\n                    75,20,10\r\n    CONTROL         \"&22\",IDC_SAMPLINGFREQ22,\"Button\",BS_AUTORADIOBUTTON,172,\r\n                    75,20,10\r\n    CONTROL         \"&44\",IDC_SAMPLINGFREQ44,\"Button\",BS_AUTORADIOBUTTON,196,\r\n                    75,20,10\r\n    CONTROL         \"Generic1\",IDC_AMPLITUDETRACKBAR,\"msctls_trackbar32\",\r\n                    WS_TABSTOP | 0x3a,110,15,20,55\r\n    GROUPBOX        \"Amplitude\",IDC_AMPLITUDEGROUP,100,5,40,85,WS_GROUP\r\n    EDITTEXT        IDC_FREQUENCYTEXT,60,70,30,15,ES_AUTOHSCROLL\r\n    EDITTEXT        IDC_AMPLITUDETEXT,105,70,30,15,ES_AUTOHSCROLL\r\n    GROUPBOX        \"Output Format\",IDC_OUTPUTFORMAT,226,5,81,85,WS_GROUP\r\n    CONTROL         \"PCM\",IDC_OF_PCM,\"Button\",BS_AUTORADIOBUTTON,231,15,66,\r\n                    11\r\n    CONTROL         \"Microsoft ADPCM\",IDC_OF_MSADPCM,\"Button\",\r\n                    BS_AUTORADIOBUTTON,231,28,71,11\r\nEND\r\n\r\nSTRINGTABLE DISCARDABLE\r\nBEGIN\r\n    IDS_SYNTHPROPNAME,    \"Synthesizer\"\r\nEND\r\n\r\n//\r\n// Version\r\n//\r\n\r\n#define VERSION_RES_BIN_NAME        \"Synth.ax\\0\"\r\n#define VERSION_RES_BIN_DESCRIPTION \"Audio Generator Source (Sample)\\0\"\r\n\r\n#define AMOVIE_SELF_REGISTER\r\n\r\n\r\n#ifndef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 3 resource.\r\n//\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // not APSTUDIO_INVOKED\r\n\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 11.00\r\n# Visual C++ Express 2010\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Synth\", \"Synth.vcxproj\", \"{BF20BC76-A330-4857-830B-80C85660478B}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Win32 = Debug|Win32\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tRelease|Win32 = Release|Win32\r\n\t\tRelease|x64 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Debug|Win32.ActiveCfg = Debug|Win32\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Debug|Win32.Build.0 = Debug|Win32\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Release|Win32.ActiveCfg = Release|Win32\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Release|Win32.Build.0 = Release|Win32\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{BF20BC76-A330-4857-830B-80C85660478B}.Release|x64.Build.0 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synth.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"8.00\"\r\n\tName=\"Synth\"\r\n\tProjectGUID=\"{BF20BC76-A330-4857-830B-80C85660478B}\"\r\n\tRootNamespace=\"Synth\"\r\n\tKeyword=\"Win32Proj\"\r\n\t>\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"\r\n\t\t/>\r\n\t\t<Platform\r\n\t\t\tName=\"x64\"\r\n\t\t/>\r\n\t</Platforms>\r\n\t<ToolFiles>\r\n\t</ToolFiles>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"Debug\"\r\n\t\t\tIntermediateDirectory=\"Debug\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\BaseClasses\\\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS\"\r\n\t\t\t\tMinimalRebuild=\"true\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"3\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"\r\n\t\t\t\tCallingConvention=\"2\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"..\\..\\BaseClasses\\Debug\\strmbasd.lib winmm.lib msvcrtd.lib Msacm32.lib comctl32.lib\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tIgnoreAllDefaultLibraries=\"true\"\r\n\t\t\t\tModuleDefinitionFile=\"synth.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"Release\"\r\n\t\t\tIntermediateDirectory=\"Release\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"2\"\r\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\BaseClasses\\\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS\"\r\n\t\t\t\tRuntimeLibrary=\"2\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"\r\n\t\t\t\tCallingConvention=\"2\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"..\\..\\BaseClasses\\Release\\strmbase.lib winmm.lib msvcrt.lib Msacm32.lib comctl32.lib\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tIgnoreAllDefaultLibraries=\"true\"\r\n\t\t\t\tModuleDefinitionFile=\"synth.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|x64\"\r\n\t\t\tOutputDirectory=\"$(PlatformName)\\$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(PlatformName)\\$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t\tTargetEnvironment=\"3\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\BaseClasses\\\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS\"\r\n\t\t\t\tMinimalRebuild=\"true\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"3\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"\r\n\t\t\t\tCallingConvention=\"2\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"strmbasd.lib winmm.lib msvcrtd.lib Msacm32.lib comctl32.lib\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tAdditionalLibraryDirectories=\"..\\..\\BaseClasses\\x64\\Debug\\\"\r\n\t\t\t\tIgnoreAllDefaultLibraries=\"true\"\r\n\t\t\t\tModuleDefinitionFile=\"synth.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tTargetMachine=\"17\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|x64\"\r\n\t\t\tOutputDirectory=\"$(PlatformName)\\$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(PlatformName)\\$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t\tTargetEnvironment=\"3\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"2\"\r\n\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\BaseClasses\\\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_WINDOWS;_USRDLL;SYNTH_EXPORTS\"\r\n\t\t\t\tRuntimeLibrary=\"2\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"\r\n\t\t\t\tCallingConvention=\"2\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"strmbase.lib winmm.lib msvcrt.lib Msacm32.lib comctl32.lib\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tAdditionalLibraryDirectories=\"..\\..\\BaseClasses\\x64\\Release\\\"\r\n\t\t\t\tIgnoreAllDefaultLibraries=\"true\"\r\n\t\t\t\tModuleDefinitionFile=\"synth.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"17\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\dynsrc.cpp\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synth.cpp\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synth.def\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synthprp.cpp\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\dynsrc.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\isynth.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\resource.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synth.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synthprp.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Resource Files\"\r\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav\"\r\n\t\t\tUniqueIdentifier=\"{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\synth.rc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synthprp.cpp",
    "content": "//------------------------------------------------------------------------------\r\n// File: SynthPrp.cpp\r\n//\r\n// Desc: DirectShow sample code - implements property page for synthesizer.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n#include <windows.h>\r\n#include <streams.h>\r\n\r\n#include <commctrl.h>\r\n#include <memory.h>\r\n#include <olectl.h>\r\n\r\n#include \"isynth.h\"\r\n#include \"synth.h\"\r\n#include \"synthprp.h\"\r\n#include \"resource.h\"\r\n\r\n#pragma warning(disable:4127)   // C4127: conditional expression is constant\r\n\r\n// -------------------------------------------------------------------------\r\n// CSynthProperties\r\n// -------------------------------------------------------------------------\r\n\r\n//\r\n// CreateInstance\r\n//\r\n\r\nCUnknown * WINAPI CSynthProperties::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)\r\n{\r\n    CUnknown *punk = new CSynthProperties(lpunk, phr);\r\n    if (punk == NULL) {\r\n        *phr = E_OUTOFMEMORY;\r\n    }\r\n\r\n    return punk;\r\n}\r\n\r\n\r\n//\r\n// Constructor\r\n//\r\n// Creaete a Property page object for the synthesizer\r\n\r\nCSynthProperties::CSynthProperties(LPUNKNOWN lpunk, HRESULT *phr)\r\n    : CBasePropertyPage(NAME(\"Synth Property Page\"), lpunk,\r\n        IDD_SYNTHPROP1,IDS_SYNTHPROPNAME)\r\n    , m_pSynth(NULL)\r\n    , m_iSweepStart(DefaultSweepStart)\r\n    , m_iSweepEnd(DefaultSweepEnd)\r\n    , m_fWindowInActive(TRUE)\r\n{\r\n    ASSERT(phr);\r\n\r\n    InitCommonControls();\r\n}\r\n\r\n//\r\n// OnConnect\r\n//\r\n// Give us the filter to communicate with\r\n\r\nHRESULT CSynthProperties::OnConnect(IUnknown *pUnknown)\r\n{\r\n    ASSERT(m_pSynth == NULL);\r\n\r\n    // Ask the filter for it's control interface\r\n\r\n    HRESULT hr = pUnknown->QueryInterface(IID_ISynth2,(void **)&m_pSynth);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    ASSERT(m_pSynth);\r\n\r\n    // Get current filter state\r\n    m_pSynth->get_BitsPerSample(&m_iBitsPerSampleOriginal);\r\n    m_pSynth->get_Waveform(&m_iWaveformOriginal);\r\n    m_pSynth->get_Frequency(&m_iFrequencyOriginal);\r\n    m_pSynth->get_Channels(&m_iChannelsOriginal);\r\n    m_pSynth->get_SamplesPerSec(&m_iSamplesPerSecOriginal);\r\n    m_pSynth->get_Amplitude(&m_iAmplitudeOriginal);\r\n    m_pSynth->get_OutputFormat(&m_OutputFormat);\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// OnDisconnect\r\n//\r\n// Release the interface\r\n\r\nHRESULT CSynthProperties::OnDisconnect()\r\n{\r\n    // Release the interface\r\n\r\n    if (m_pSynth == NULL) {\r\n        return E_UNEXPECTED;\r\n    }\r\n\r\n    m_pSynth->put_Waveform(m_iWaveformOriginal);\r\n    m_pSynth->put_Frequency(m_iFrequencyOriginal);\r\n    m_pSynth->put_Amplitude(m_iAmplitudeOriginal);\r\n\r\n    m_pSynth->put_Channels(m_iChannelsOriginal);\r\n    m_pSynth->put_BitsPerSample(m_iBitsPerSampleOriginal);\r\n    m_pSynth->put_SamplesPerSec(m_iSamplesPerSecOriginal);\r\n\r\n    m_pSynth->put_OutputFormat(m_OutputFormat);\r\n\r\n    m_pSynth->Release();\r\n    m_pSynth = NULL;\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// OnActivate\r\n//\r\n// Called on dialog creation\r\n\r\nHRESULT CSynthProperties::OnActivate(void)\r\n{\r\n    InitPropertiesDialog(m_hwnd);\r\n\r\n    ASSERT(m_hwndFreqSlider);\r\n\r\n    m_fWindowInActive = FALSE;\r\n    \r\n    return NOERROR;\r\n}\r\n\r\n//\r\n// OnDeactivate\r\n//\r\n// Called on dialog destruction\r\n\r\nHRESULT\r\nCSynthProperties::OnDeactivate(void)\r\n{\r\n    m_fWindowInActive = TRUE;\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// OnApplyChanges\r\n//\r\n// User pressed the Apply button, remember the current settings\r\n\r\nHRESULT CSynthProperties::OnApplyChanges(void)\r\n{\r\n    m_pSynth->get_BitsPerSample(&m_iBitsPerSampleOriginal);\r\n    m_pSynth->get_Waveform(&m_iWaveformOriginal);\r\n    m_pSynth->get_Frequency(&m_iFrequencyOriginal);\r\n    m_pSynth->get_Channels(&m_iChannelsOriginal);\r\n    m_pSynth->get_SamplesPerSec(&m_iSamplesPerSecOriginal);\r\n    m_pSynth->get_Amplitude(&m_iAmplitudeOriginal);\r\n    m_pSynth->get_OutputFormat(&m_OutputFormat);\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// OnReceiveMessages\r\n//\r\n// Handles the messages for our property window\r\n\r\nINT_PTR CSynthProperties::OnReceiveMessage(HWND hwnd\r\n                                         , UINT uMsg\r\n                                         , WPARAM wParam\r\n                                         , LPARAM lParam)\r\n{\r\n    HRESULT hr;\r\n\r\n    if(m_fWindowInActive)\r\n        return FALSE;\r\n\r\n    switch (uMsg) {\r\n\r\n    case WM_PROPERTYPAGE_ENABLE:\r\n        // Our private message that our owning filter sends us when changing to a Run / Stop / Pause\r\n        // state.  if lParam, then enable the controls which affect the format; if not lParam, then\r\n        // disable the controls that affect the format.\r\n\r\n        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ11), (BOOL) lParam);\r\n        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ22), (BOOL) lParam);\r\n        EnableWindow (GetDlgItem (hwnd, IDC_SAMPLINGFREQ44), (BOOL) lParam);\r\n\r\n        EnableWindow (GetDlgItem (hwnd, IDC_BITSPERSAMPLE8),  (BOOL) lParam);\r\n        EnableWindow (GetDlgItem (hwnd, IDC_BITSPERSAMPLE16), (BOOL) lParam);\r\n\r\n        EnableWindow (GetDlgItem (hwnd, IDC_CHANNELS1), (BOOL) lParam);\r\n        EnableWindow (GetDlgItem (hwnd, IDC_CHANNELS2), (BOOL) lParam);\r\n        break;\r\n\r\n    case WM_VSCROLL:\r\n        if ((HWND) lParam == m_hwndFreqSlider)\r\n            OnFreqSliderNotification(LOWORD (wParam), HIWORD (wParam));\r\n        else if ((HWND) lParam == m_hwndAmplitudeSlider)\r\n            OnAmpSliderNotification(LOWORD (wParam), HIWORD (wParam));\r\n        SetDirty();\r\n        return TRUE;\r\n\r\n    case WM_COMMAND:\r\n\r\n        switch (LOWORD(wParam)) {\r\n\r\n        case IDC_FREQUENCYTEXT:\r\n        {\r\n            int iNotify = HIWORD (wParam);\r\n\r\n            if (iNotify == EN_KILLFOCUS) {\r\n                BOOL fOK;\r\n\r\n                int iPos = GetDlgItemInt (hwnd, IDC_FREQUENCYTEXT, &fOK, FALSE);\r\n                int iMaxFreq;\r\n\r\n                m_pSynth->get_SamplesPerSec(&iMaxFreq);\r\n                iMaxFreq /= 2;\r\n\r\n                if (!fOK || (iPos > iMaxFreq || iPos < 0)) {\r\n                    int iCurrentFreq;\r\n                    m_pSynth->get_Frequency(&iCurrentFreq);\r\n                    SetDlgItemInt (hwnd, IDC_FREQUENCYTEXT, iCurrentFreq, FALSE);\r\n                    break;\r\n                }\r\n\r\n                SendMessage(m_hwndFreqSlider, TBM_SETPOS, TRUE, (LPARAM) iMaxFreq - iPos);\r\n                m_pSynth->put_Frequency(iPos);\r\n                SetDirty();\r\n            }\r\n        }\r\n        break;\r\n\r\n        case IDC_AMPLITUDETEXT:\r\n        {\r\n            int iNotify = HIWORD (wParam);\r\n\r\n            if (iNotify == EN_KILLFOCUS) {\r\n                BOOL fOK;\r\n\r\n                int iPos = GetDlgItemInt (hwnd, IDC_AMPLITUDETEXT, &fOK, FALSE);\r\n\r\n                if (!fOK || (iPos > MaxAmplitude || iPos < 0)) {\r\n                    int iCurrentAmplitude;\r\n\r\n                    m_pSynth->get_Amplitude(&iCurrentAmplitude);\r\n                    SetDlgItemInt (hwnd, IDC_AMPLITUDETEXT, iCurrentAmplitude, FALSE);\r\n                    break;\r\n                }\r\n\r\n                SendMessage(m_hwndAmplitudeSlider, TBM_SETPOS, TRUE, (LPARAM) MaxAmplitude - iPos);\r\n                m_pSynth->put_Amplitude(iPos);\r\n                SetDirty();\r\n            }\r\n        }\r\n        break;\r\n\r\n        case IDC_SAMPLINGFREQ11:\r\n            m_pSynth->put_SamplesPerSec(11025);\r\n            RecalcFreqSlider();\r\n            SetDirty();\r\n            break;\r\n        case IDC_SAMPLINGFREQ22:\r\n            m_pSynth->put_SamplesPerSec(22050);\r\n            RecalcFreqSlider();\r\n            SetDirty();\r\n            break;\r\n        case IDC_SAMPLINGFREQ44:\r\n            m_pSynth->put_SamplesPerSec(44100);\r\n            RecalcFreqSlider();\r\n            SetDirty();\r\n            break;\r\n\r\n\r\n        case IDC_BITSPERSAMPLE8:\r\n            m_pSynth->put_BitsPerSample(8);\r\n            SetDirty();\r\n            break;\r\n        case IDC_BITSPERSAMPLE16:\r\n            m_pSynth->put_BitsPerSample(16);\r\n            SetDirty();\r\n            break;\r\n\r\n\r\n        case IDC_CHANNELS1:\r\n            m_pSynth->put_Channels(1);\r\n            SetDirty();\r\n            break;\r\n        case IDC_CHANNELS2:\r\n            m_pSynth->put_Channels(2);\r\n            SetDirty();\r\n            break;\r\n        \r\n\r\n        case IDC_WAVESINE:\r\n            m_pSynth->put_Waveform(WAVE_SINE);\r\n            SetDirty();\r\n            break;\r\n        case IDC_WAVESQUARE:\r\n            m_pSynth->put_Waveform(WAVE_SQUARE);\r\n            SetDirty();\r\n            break;\r\n        case IDC_WAVESAWTOOTH:\r\n            m_pSynth->put_Waveform(WAVE_SAWTOOTH);\r\n            SetDirty();\r\n            break;\r\n        case IDC_WAVESWEEP:\r\n            m_pSynth->put_Waveform(WAVE_SINESWEEP);\r\n            SetDirty();\r\n            break;\r\n\r\n        case IDC_OF_PCM:\r\n            hr = m_pSynth->put_OutputFormat(SYNTH_OF_PCM);\r\n            if (SUCCEEDED(hr)) {\r\n                EnableBitsPerSampleRadioButtons(hwnd, TRUE);\r\n            } else {\r\n                MessageBeep(MB_ICONASTERISK);\r\n            }\r\n\r\n            SetDirty();\r\n            break;\r\n\r\n        case IDC_OF_MSADPCM:\r\n            hr = m_pSynth->put_OutputFormat(SYNTH_OF_MS_ADPCM);\r\n            if (SUCCEEDED(hr)) {\r\n                EnableBitsPerSampleRadioButtons(hwnd, FALSE);\r\n            } else {\r\n                MessageBeep(MB_ICONASTERISK);\r\n            }\r\n            SetDirty();\r\n            break;\r\n\r\n        default:\r\n            break;\r\n\r\n        }\r\n        return TRUE;\r\n\r\n    case WM_DESTROY:\r\n        return TRUE;\r\n\r\n    default:\r\n        return FALSE;\r\n\r\n    }\r\n    return TRUE;\r\n}\r\n\r\n\r\n//\r\n// InitPropertiesDialog\r\n//\r\n\r\nvoid\r\nCSynthProperties::InitPropertiesDialog(HWND hwndParent)\r\n{\r\n    m_hwndFreqSlider = GetDlgItem (hwndParent, IDC_FREQTRACKBAR);\r\n    m_hwndFreqText  = GetDlgItem (hwndParent, IDC_FREQUENCYTEXT);\r\n    m_hwndAmplitudeSlider = GetDlgItem (hwndParent, IDC_AMPLITUDETRACKBAR);\r\n    m_hwndAmplitudeText  = GetDlgItem (hwndParent, IDC_AMPLITUDETEXT);\r\n\r\n    // Sampling Frequency\r\n    int i=0;\r\n    switch (m_iSamplesPerSecOriginal) {\r\n        case 11025: i = IDC_SAMPLINGFREQ11; break;\r\n        case 22050: i = IDC_SAMPLINGFREQ22; break;\r\n        case 44100: i = IDC_SAMPLINGFREQ44; break;\r\n        default:\r\n            ASSERT(0);  break;\r\n    }\r\n    CheckRadioButton(hwndParent,\r\n        IDC_SAMPLINGFREQ11,\r\n        IDC_SAMPLINGFREQ44,\r\n        i);\r\n\r\n    // BitsPerSample\r\n    CheckRadioButton(hwndParent,\r\n                IDC_BITSPERSAMPLE8,\r\n                IDC_BITSPERSAMPLE16,\r\n                IDC_BITSPERSAMPLE8 + m_iBitsPerSampleOriginal / 8 - 1);\r\n\r\n    // Waveform 0 == sine, 1 == square, ...\r\n    CheckRadioButton(hwndParent,\r\n                IDC_WAVESINE,\r\n                IDC_WAVESWEEP,\r\n                IDC_WAVESINE + m_iWaveformOriginal);\r\n\r\n    // Channels\r\n    CheckRadioButton(hwndParent,\r\n                IDC_CHANNELS1,\r\n                IDC_CHANNELS2,\r\n                IDC_CHANNELS1 + m_iChannelsOriginal - 1);\r\n\r\n    CheckRadioButton(hwndParent,\r\n                IDC_OF_PCM,\r\n                IDC_OF_MSADPCM,\r\n                IDC_OF_PCM + (int)m_OutputFormat);\r\n\r\n    if(SYNTH_OF_MS_ADPCM == m_OutputFormat) {\r\n        EnableBitsPerSampleRadioButtons(hwndParent, FALSE); \r\n    } else {\r\n        // The synth filter only supports two output formats: SYNTH_OF_PCM and SYNTH_OF_MS_ADPCM.\r\n        ASSERT(SYNTH_OF_PCM == m_OutputFormat);\r\n        \r\n        EnableBitsPerSampleRadioButtons(hwndParent, TRUE); \r\n    }\r\n\r\n    //\r\n    // Frequency trackbar\r\n    //\r\n\r\n    RecalcFreqSlider();\r\n\r\n    //\r\n    //  Amplitude trackbar\r\n    //\r\n\r\n    SendMessage(m_hwndAmplitudeSlider, TBM_SETRANGE, TRUE,\r\n        MAKELONG(MinAmplitude, MaxAmplitude) );\r\n\r\n    SendMessage(m_hwndAmplitudeSlider, TBM_SETTIC, 0,\r\n        ((MinAmplitude + MaxAmplitude) / 2));\r\n\r\n    SendMessage(m_hwndAmplitudeSlider, TBM_SETPOS, TRUE,\r\n        (LPARAM) (MaxAmplitude - m_iAmplitudeOriginal));\r\n\r\n    SetDlgItemInt (hwndParent, IDC_AMPLITUDETEXT,\r\n        m_iAmplitudeOriginal, TRUE);\r\n}\r\n\r\n\r\n//\r\n// RecalcFreqSlider\r\n//\r\n// Set the range, current settings for the Freq scrollbar\r\n\r\nvoid\r\nCSynthProperties::RecalcFreqSlider(void)\r\n{\r\n    int iPos, iMaxFreq;\r\n\r\n    // Limit the frequency to one half the sampling frequency\r\n\r\n    m_pSynth->get_SamplesPerSec(&iMaxFreq);\r\n    iMaxFreq /= 2;\r\n    m_pSynth->get_Frequency(&iPos);\r\n    if (iPos > iMaxFreq)\r\n        iPos = iMaxFreq;\r\n\r\n    SendMessage(m_hwndFreqSlider, TBM_SETRANGE, TRUE,\r\n        MAKELONG(0, iMaxFreq));\r\n\r\n    SendMessage(m_hwndFreqSlider, TBM_SETTIC, 0,\r\n        iMaxFreq / 2);\r\n\r\n    SendMessage(m_hwndFreqSlider, TBM_SETPOS, TRUE,\r\n        (LPARAM) (iMaxFreq - iPos));\r\n\r\n    SendMessage(m_hwndFreqSlider, TBM_SETPAGESIZE, 0, 10);\r\n\r\n    SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE,\r\n        MAKELONG (iMaxFreq - m_iSweepEnd, iMaxFreq - m_iSweepStart));\r\n\r\n    SetDlgItemInt (m_hwnd, IDC_FREQUENCYTEXT,\r\n        iPos, TRUE);\r\n\r\n}\r\n\r\n//\r\n// OnFreqSliderNotification\r\n//\r\n// Handle the notification meesages from the slider control\r\n\r\nvoid\r\nCSynthProperties::OnFreqSliderNotification(WPARAM wParam, WORD wPosition)\r\n{\r\n    int MaxFreq;\r\n    int Freq;\r\n    int SliderPos;\r\n\r\n    switch (wParam) {\r\n\r\n    case TB_ENDTRACK:\r\n    case TB_THUMBTRACK:\r\n    case TB_LINEDOWN:\r\n    case TB_LINEUP: {\r\n        // max frequency of slider is half the sampling frequency\r\n        m_pSynth->get_SamplesPerSec (&MaxFreq);\r\n        MaxFreq /= 2;\r\n        SliderPos = (int) SendMessage(m_hwndFreqSlider, TBM_GETPOS, 0, 0L);\r\n        Freq = MaxFreq - SliderPos;\r\n        m_pSynth->put_Frequency (Freq);\r\n\r\n        // Set the end of sweep to the current slider pos\r\n        if (!(GetKeyState (VK_SHIFT) & 0x8000)) {\r\n            m_iSweepEnd = Freq;\r\n        }\r\n\r\n        // Set the start of the sweep range if SHIFT key is pressed\r\n        if (GetKeyState (VK_SHIFT) & 0x8000) {\r\n            m_iSweepStart = Freq;\r\n        }\r\n        m_pSynth->put_SweepRange (m_iSweepStart, m_iSweepEnd);\r\n\r\n        if (m_iSweepEnd > m_iSweepStart)\r\n            SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE,\r\n                MAKELONG (MaxFreq - m_iSweepEnd, MaxFreq - m_iSweepStart));\r\n        else\r\n            SendMessage(m_hwndFreqSlider, TBM_SETSEL, TRUE,\r\n                MAKELONG (MaxFreq - m_iSweepStart, MaxFreq - m_iSweepEnd));\r\n\r\n        SetDlgItemInt (m_hwnd, IDC_FREQUENCYTEXT, Freq, TRUE);\r\n\r\n    }\r\n    break;\r\n\r\n    }\r\n}\r\n\r\n//\r\n// OnAmpSliderNotification\r\n//\r\n// Handle the notification meesages from the slider control\r\n\r\nvoid\r\nCSynthProperties::OnAmpSliderNotification(WPARAM wParam, WORD wPosition)\r\n{\r\n    switch (wParam) {\r\n\r\n    case TB_ENDTRACK:\r\n    case TB_THUMBTRACK:\r\n    case TB_LINEDOWN:\r\n    case TB_LINEUP: {\r\n        int Level = (int) SendMessage(m_hwndAmplitudeSlider, TBM_GETPOS, 0, 0L);\r\n        m_pSynth->put_Amplitude (MaxAmplitude - Level);\r\n        SetDlgItemInt (m_hwnd, IDC_AMPLITUDETEXT, MaxAmplitude - Level, TRUE);\r\n    }\r\n    break;\r\n\r\n    }\r\n}\r\n\r\n//\r\n// SetDirty\r\n//\r\n// notifies the property page site of changes\r\n\r\nvoid\r\nCSynthProperties::SetDirty()\r\n{\r\n    m_bDirty = TRUE;\r\n    if (m_pPageSite)\r\n        m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY);\r\n}\r\n\r\nvoid\r\nCSynthProperties::EnableBitsPerSampleRadioButtons(HWND hwndParent, BOOL fEnable)\r\n{\r\n    EnableWindow (GetDlgItem (hwndParent, IDC_BITSPERSAMPLE8),  fEnable);\r\n    EnableWindow (GetDlgItem (hwndParent, IDC_BITSPERSAMPLE16), fEnable);\r\n}\r\n"
  },
  {
    "path": "source_code/synth_deprecated/synthprp.h",
    "content": "//------------------------------------------------------------------------------\r\n// File: SynthPrp.h\r\n//\r\n// Desc: DirectShow sample code - definition of CSynthProperties class.\r\n//\r\n// Copyright (c) Microsoft Corporation.  All rights reserved.\r\n//------------------------------------------------------------------------------\r\n\r\n\r\nclass CSynthProperties : public CBasePropertyPage {\r\n\r\npublic:\r\n\r\n    CSynthProperties(LPUNKNOWN lpUnk, HRESULT *phr);\r\n    static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);\r\n\r\n    HRESULT OnConnect(IUnknown *pUnknown);\r\n    HRESULT OnDisconnect();\r\n    HRESULT OnActivate();\r\n    HRESULT OnDeactivate();\r\n    HRESULT OnApplyChanges();\r\n\r\n    INT_PTR OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);\r\n\r\nprivate:\r\n\r\n    static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r\n\r\n    void    InitPropertiesDialog(HWND hwndParent);\r\n    void    OnFreqSliderNotification(WPARAM wParam, WORD wPosition);\r\n    void    OnAmpSliderNotification(WPARAM wParam, WORD wPosition);\r\n    void    RecalcFreqSlider(void);\r\n    void    SetDirty(void);\r\n    void    EnableBitsPerSampleRadioButtons(HWND hwndParent, BOOL fEnable);\r\n\r\n    HWND    m_hwndFreqSlider;           // handle of slider\r\n    HWND    m_hwndFreqText;             // Handle of frequency text window\r\n    HWND    m_hwndAmplitudeSlider;      // handle of slider\r\n    HWND    m_hwndAmplitudeText;        // Handle of amplitude text window\r\n\r\n    int     m_iWaveformOriginal;        // WAVE_SINE ...\r\n    int     m_iFrequencyOriginal;       // if not using sweep, this is the frequency\r\n    int     m_iBitsPerSampleOriginal;   // 8 or 16\r\n    int     m_iChannelsOriginal;        // 1 or 2\r\n    int     m_iSamplesPerSecOriginal;   // 8000, 11025, ...\r\n    int     m_iAmplitudeOriginal;       // 0 to 100\r\n    int     m_iSweepStart;              // Sweep range on freq slider\r\n    int     m_iSweepEnd;\r\n\r\n    SYNTH_OUTPUT_FORMAT m_OutputFormat;\r\n\r\n    BOOL    m_fWindowInActive;          // TRUE ==> dialog is being destroyed\r\n\r\n    ISynth2 *m_pSynth;                  // Interface to the synthsizer\r\n};\r\n"
  },
  {
    "path": "source_code/synth_deprecated/useless_synth.cpp",
    "content": "\r\n\r\n#include <windows.h>\r\n#include <streams.h>\r\n\r\n#include <math.h>\r\n#include <mmreg.h>\r\n#include <msacm.h>\r\n\r\n#include <initguid.h>\r\n#if (1100 > _MSC_VER)\r\n#include <olectlid.h>\r\n#else\r\n#include <olectl.h>\r\n#endif\r\n\r\n\r\n#define _AUDIOSYNTH_IMPLEMENTATION_\r\n\r\n#include \"DynSrc.h\"\r\n#include \"isynth.h\"\r\n#include \"synth.h\"\r\n#include \"synthprp.h\"\r\n\r\n\r\nHRESULT LoopbackCapture(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize, WAVEFORMATEX* ifNotNullThenJustSetTypeOnly);\r\n\r\n//\r\n// FillAudioBuffer\r\n//\r\n// This actually fills it with the sin wave by copying it verbatim into the output...\r\n//\r\nvoid CAudioSynth::FillPCMAudioBuffer(const WAVEFORMATEX& wfex, BYTE pBuf[], int iSize)\r\n{\r\n    BOOL fCalcCache = FALSE;\r\n\r\n    // The caller should always hold the state lock because this\r\n    // function uses m_iFrequency,  m_iFrequencyLast, m_iWaveform\r\n    // m_iWaveformLast, m_iAmplitude, m_iAmplitudeLast, m_iWaveCacheIndex\r\n    // m_iWaveCacheSize, m_bWaveCache and m_wWaveCache.  The caller should\r\n    // also hold the state lock because this function calls CalcCache().\r\n    ASSERT(CritCheckIn(m_pStateLock));\r\n\r\n    // Only realloc the cache if the format has changed !\r\n    if(m_iFrequency != m_iFrequencyLast)\r\n    {\r\n        fCalcCache = TRUE;\r\n        m_iFrequencyLast = m_iFrequency;\r\n    }\r\n    if(m_iWaveform != m_iWaveformLast)\r\n    {\r\n        fCalcCache = TRUE;\r\n        m_iWaveformLast = m_iWaveform;\r\n    }\r\n    if(m_iAmplitude != m_iAmplitudeLast)\r\n    {\r\n        fCalcCache = TRUE;\r\n        m_iAmplitudeLast = m_iAmplitude;\r\n    }\r\n\r\n    if(fCalcCache)\r\n    {\r\n\t\t// recalculate the sin wave...\r\n        CalcCache(wfex);\r\n    }\r\n\r\n\t  // sin wave (old way)\r\n      // Copy cache to output buffers\r\n      copyCacheToOutputBuffers(wfex, pBuf, iSize);\r\n}\r\n\r\n//\r\n// put_SamplesPerSec\r\n//\r\nSTDMETHODIMP CSynthFilter::put_SamplesPerSec(int SamplesPerSec) \r\n{\r\n    // This function holds the state lock because it does not want\r\n    // the filter's format type state or its' connection state\r\n    // to change between the call to put_SamplesPerSec() and the call to\r\n    // ReconnectWithNewFormat().\r\n    CAutoLock lStateLock(pStateLock());\r\n\r\n    HRESULT hr = m_Synth->put_SamplesPerSec(SamplesPerSec);\r\n    if( FAILED( hr ) ) {\r\n        return hr;\r\n    }\r\n\r\n    ReconnectWithNewFormat ();\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_SamplesPerSec: %d\"), SamplesPerSec));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Amplitude\r\n//\r\nSTDMETHODIMP CSynthFilter::put_Amplitude(int Amplitude)\r\n{\r\n    m_Synth->put_Amplitude (Amplitude);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Amplitude: %d\"), Amplitude));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n\r\n//\r\n// put_SweepRange\r\n//\r\nSTDMETHODIMP CSynthFilter::put_SweepRange(int SweepStart, int SweepEnd) \r\n{\r\n    m_Synth->put_SweepRange (SweepStart, SweepEnd);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_SweepRange: %d %d\"), SweepStart, SweepEnd));\r\n    return NOERROR;\r\n}\r\n\r\n\r\nSTDMETHODIMP CSynthFilter::put_OutputFormat(SYNTH_OUTPUT_FORMAT ofOutputFormat) \r\n{\r\n    // This function holds the state lock because it does not want\r\n    // the filter's format type state or its' connection state\r\n    // to change between the call to put_OutputFormat() and the call to\r\n    // ReconnectWithNewFormat().\r\n    CAutoLock lStateLock(pStateLock());    \r\n\r\n    HRESULT hr = m_Synth->put_OutputFormat(ofOutputFormat);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    ReconnectWithNewFormat();\r\n    return S_OK;\r\n}\r\n\r\n\r\n//\r\n// put_BitsPerSample\r\n//\r\nSTDMETHODIMP CSynthFilter::put_BitsPerSample(int BitsPerSample) \r\n{\r\n    // This function holds the state lock because it does not want\r\n    // the filter's format type state or its' connection state\r\n    // to change between the call to put_BitsPerSample() and the call to\r\n    // ReconnectWithNewFormat().\r\n    CAutoLock lStateLock(pStateLock());\r\n\r\n    HRESULT hr = m_Synth->put_BitsPerSample(BitsPerSample);\r\n    if( FAILED( hr ) ) {\r\n        return hr;\r\n    }\r\n\r\n    ReconnectWithNewFormat ();\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_BitsPerSample: %d\"), BitsPerSample));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Channels\r\n//\r\nSTDMETHODIMP CSynthFilter::put_Channels(int Channels) \r\n{\r\n    // This function holds the state lock because it does not want\r\n    // the filter's format type state or its' connection state\r\n    // to change between the call to put_Channels() and the call to\r\n    // ReconnectWithNewFormat().\r\n    CAutoLock lStateLock(pStateLock());\r\n\r\n    HRESULT hr = m_Synth->put_Channels(Channels);\r\n    if( FAILED( hr ) ) {\r\n        return hr;\r\n    }\r\n\r\n    ReconnectWithNewFormat ();\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Channels: %d\"), Channels));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// CSynthFilter::Destructor\r\n//\r\nCSynthFilter::~CSynthFilter(void) \r\n{\r\n    //\r\n    //  Base class will free our pins\r\n    //\r\n}\r\n\r\n\r\n\r\n\r\n//\r\n// NonDelegatingQueryInterface\r\n//\r\n// Reveal our property page, persistance, and control interfaces\r\n\r\nSTDMETHODIMP CSynthFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)\r\n{\r\n    if (riid == IID_ISynth2) {\r\n        return GetInterface((ISynth2 *) this, ppv);\r\n    }\r\n    else if (riid == IID_IPersistStream) {\r\n        return GetInterface((IPersistStream *) this, ppv);\r\n    }\r\n    else if (riid == IID_ISpecifyPropertyPages) {\r\n        return GetInterface((ISpecifyPropertyPages *) this, ppv);\r\n    } \r\n    else {\r\n        return CDynamicSource::NonDelegatingQueryInterface(riid, ppv);\r\n    }\r\n}\r\n\r\n\r\n//\r\n// GetPages\r\n//\r\nSTDMETHODIMP CSynthFilter::GetPages(CAUUID * pPages) \r\n{\r\n    CheckPointer(pPages,E_POINTER);\r\n\r\n    pPages->cElems = 1;\r\n    pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));\r\n    if (pPages->pElems == NULL) {\r\n        return E_OUTOFMEMORY;\r\n    }\r\n\r\n    *(pPages->pElems) = CLSID_SynthPropertyPage;\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// --- IPersistStream ---\r\n// -------------------------------------------------------------------------\r\n\r\n#define WRITEOUT(var)   hr = pStream->Write(&var, sizeof(var), NULL); \\\r\n                        if (FAILED(hr)) return hr;\r\n\r\n#define READIN(var)     hr = pStream->Read(&var, sizeof(var), NULL); \\\r\n                        if (FAILED(hr)) return hr;\r\n\r\n\r\n\r\n// appears this one is called by directsound...\r\n\r\nHRESULT CSynthFilter::WriteToStream(IStream *pStream)\r\n{\r\n    CheckPointer(pStream,E_POINTER);\r\n\r\n    HRESULT hr;\r\n    int i, k;\r\n\r\n    get_Frequency (&i);  \r\n    WRITEOUT(i);\r\n\r\n    get_Waveform (&i);\r\n    WRITEOUT(i);\r\n\r\n    get_Channels (&i);\r\n    WRITEOUT(i);\r\n\r\n    get_BitsPerSample (&i);\r\n    WRITEOUT(i);\r\n\r\n    get_SamplesPerSec (&i);\r\n    WRITEOUT(i);\r\n\r\n    get_Amplitude (&i);\r\n    WRITEOUT(i);\r\n\r\n    get_SweepRange (&i, &k);\r\n    WRITEOUT(i);\r\n    WRITEOUT(k);\r\n\r\n\t//#get_OutputFormat((SYNTH_OUTPUT_FORMAT*)&i);\r\n\ti = WAVE_FORMAT_PCM;\r\n    WRITEOUT(i);\r\n\r\n    return hr;\r\n}\r\n\r\n// I think this is just to read from the properties pages...I think...\r\n\r\nHRESULT CSynthFilter::ReadFromStream(IStream *pStream)\r\n{\r\n    CheckPointer(pStream,E_POINTER);\r\n\r\n    if (GetSoftwareVersion() != mPS_dwFileVersion)\r\n        return E_FAIL;\r\n\r\n    HRESULT hr;\r\n    int i, k;\r\n\r\n    READIN(i); // reads 4 bytes...\r\n    put_Frequency(i);\r\n\r\n    READIN(i);\r\n    put_Waveform (i);\r\n\r\n    READIN(i);\r\n    put_Channels (i);\r\n\r\n    READIN(i);\r\n    put_BitsPerSample (i);\r\n\r\n    READIN(i);\r\n    put_SamplesPerSec (i);\r\n\r\n    READIN(i);\r\n    put_Amplitude (i);\r\n\r\n    READIN(i);\r\n    READIN(k);\r\n    put_SweepRange (i, k);\r\n\r\n    READIN(i);\r\n    put_OutputFormat((SYNTH_OUTPUT_FORMAT)i);\r\n\r\n    return hr;\r\n}\r\n\r\n\r\n\r\n//\r\n// get_Frequency\r\n//\r\nSTDMETHODIMP CAudioSynth::get_Frequency(int *pFrequency)\r\n{\r\n    CheckPointer(pFrequency,E_POINTER);\r\n\r\n    *pFrequency = m_iFrequency;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Frequency: %d\"), *pFrequency));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Frequency\r\n//\r\nSTDMETHODIMP CAudioSynth::put_Frequency(int Frequency)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_iFrequency = Frequency;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Frequency: %d\"), Frequency));\r\n    return NOERROR;\r\n}\r\n\r\n//\r\n// get_Waveform\r\n//\r\nSTDMETHODIMP CAudioSynth::get_Waveform(int *pWaveform)\r\n{\r\n    CheckPointer(pWaveform,E_POINTER);\r\n    *pWaveform = m_iWaveform;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Waveform: %d\"), *pWaveform));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Waveform\r\n//\r\nSTDMETHODIMP CAudioSynth::put_Waveform(int Waveform)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_iWaveform = Waveform;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Waveform: %d\"), Waveform));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_Channels\r\n//\r\nSTDMETHODIMP CAudioSynth::get_Channels(int *pChannels)\r\n{\r\n    CheckPointer(pChannels,E_POINTER);\r\n\r\n    *pChannels = m_wChannels;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Channels: %d\"), *pChannels));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Channels\r\n//\r\nSTDMETHODIMP CAudioSynth::put_Channels(int Channels)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_wChannels = (WORD) Channels;\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_BitsPerSample\r\n//\r\nSTDMETHODIMP CAudioSynth::get_BitsPerSample(int *pBitsPerSample)\r\n{\r\n    CheckPointer(pBitsPerSample,E_POINTER);\r\n\r\n    *pBitsPerSample = m_wBitsPerSample;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_BitsPerSample: %d\"), *pBitsPerSample));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_BitsPerSample\r\n//\r\nSTDMETHODIMP CAudioSynth::put_BitsPerSample(int BitsPerSample)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_wBitsPerSample = (WORD) BitsPerSample;\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_SamplesPerSec\r\n//\r\nSTDMETHODIMP CAudioSynth::get_SamplesPerSec(int *pSamplesPerSec)\r\n{\r\n    CheckPointer(pSamplesPerSec,E_POINTER);\r\n\r\n    *pSamplesPerSec = m_dwSamplesPerSec;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_SamplesPerSec: %d\"), *pSamplesPerSec));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_SamplesPerSec\r\n//\r\nSTDMETHODIMP CAudioSynth::put_SamplesPerSec(int SamplesPerSec)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_dwSamplesPerSec = SamplesPerSec;\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_SynthFormat\r\n//\r\nSTDMETHODIMP CAudioSynth::put_SynthFormat(int Channels, int BitsPerSample,\r\n                                          int SamplesPerSec)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_wChannels = (WORD) Channels;\r\n    m_wBitsPerSample = (WORD) BitsPerSample;\r\n    m_dwSamplesPerSec = SamplesPerSec;\r\n\r\n    DbgLog((LOG_TRACE, 1, TEXT(\"put_SynthFormat: %d-bit %d-channel %dHz\"),\r\n        BitsPerSample, Channels, SamplesPerSec));\r\n\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_Amplitude\r\n//\r\nSTDMETHODIMP CAudioSynth::get_Amplitude(int *pAmplitude)\r\n{\r\n    CheckPointer(pAmplitude,E_POINTER);\r\n\r\n    *pAmplitude =  m_iAmplitude;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Amplitude: %d\"), *pAmplitude));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Amplitude\r\n//\r\nSTDMETHODIMP CAudioSynth::put_Amplitude(int Amplitude)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    if(Amplitude > MaxAmplitude || Amplitude < MinAmplitude)\r\n        return E_INVALIDARG;\r\n\r\n    m_iAmplitude = Amplitude;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Amplitude: %d\"), Amplitude));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_SweepRange\r\n//\r\nSTDMETHODIMP CAudioSynth::get_SweepRange(int *pSweepStart, int *pSweepEnd)\r\n{\r\n    CheckPointer(pSweepStart,E_POINTER);\r\n    CheckPointer(pSweepEnd,E_POINTER);\r\n\r\n    *pSweepStart = m_iSweepStart;\r\n    *pSweepEnd   = m_iSweepEnd;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_SweepStart: %d %d\"), *pSweepStart, *pSweepEnd));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_SweepRange\r\n//\r\nSTDMETHODIMP CAudioSynth::put_SweepRange(int SweepStart, int SweepEnd)\r\n{\r\n    CAutoLock l(m_pStateLock);\r\n\r\n    m_iSweepStart = SweepStart;\r\n    m_iSweepEnd = SweepEnd;\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_SweepRange: %d %d\"), SweepStart, SweepEnd));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_OutputFormat\r\n//\r\nSTDMETHODIMP CAudioSynth::get_OutputFormat(SYNTH_OUTPUT_FORMAT *pOutputFormat)\r\n{\r\n    CheckPointer(pOutputFormat, E_POINTER);\r\n\r\n    ValidateReadWritePtr(pOutputFormat, sizeof(SYNTH_OUTPUT_FORMAT));\r\n\r\n    switch(m_wFormatTag)\r\n    {\r\n        case WAVE_FORMAT_PCM:\r\n            *pOutputFormat = SYNTH_OF_PCM;\r\n            break;\r\n\r\n        case WAVE_FORMAT_ADPCM:\r\n            *pOutputFormat = SYNTH_OF_MS_ADPCM;\r\n            break;\r\n\r\n        default:\r\n            return E_UNEXPECTED;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n//\r\n// put_OutputFormat\r\n//\r\nSTDMETHODIMP CAudioSynth::put_OutputFormat(SYNTH_OUTPUT_FORMAT ofOutputFormat)\r\n{\r\n    CAutoLock l(m_pStateLock);    \r\n\r\n    switch(ofOutputFormat)\r\n    {\r\n        case SYNTH_OF_PCM:\r\n            m_wFormatTag = WAVE_FORMAT_PCM;\r\n            break;\r\n\r\n        case SYNTH_OF_MS_ADPCM:\r\n            m_wFormatTag = WAVE_FORMAT_ADPCM;\r\n            break;\r\n\r\n        default:\r\n            return E_INVALIDARG;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\n\r\n\r\n// -------------------------------------------------------------------------\r\n// ISynth2, the control interface for the synthesizer\r\n// -------------------------------------------------------------------------\r\n\r\n//\r\n// get_Frequency\r\n//\r\nSTDMETHODIMP CSynthFilter::get_Frequency(int *Frequency) \r\n{\r\n    m_Synth->get_Frequency(Frequency);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Frequency: %d\"), *Frequency));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Frequency\r\n//\r\nSTDMETHODIMP CSynthFilter::put_Frequency(int Frequency) \r\n{\r\n    m_Synth->put_Frequency (Frequency);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Frequency: %d\"), Frequency));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_Waveform\r\n//\r\nSTDMETHODIMP CSynthFilter::get_Waveform(int *Waveform) \r\n{\r\n    m_Synth->get_Waveform (Waveform);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Waveform: %d\"), *Waveform));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// put_Waveform\r\n//\r\nSTDMETHODIMP CSynthFilter::put_Waveform(int Waveform) \r\n{\r\n    m_Synth->put_Waveform (Waveform);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"put_Waveform: %d\"), Waveform));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n//\r\n// get_Channels\r\n//\r\nSTDMETHODIMP CSynthFilter::get_Channels(int *Channels) \r\n{\r\n    HRESULT hr = m_Synth->get_Channels( Channels );\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Channels: %d\"), *Channels));\r\n    return hr;\r\n}\r\n\r\n\r\n//\r\n// If the format changes, we need to reconnect\r\n//\r\nvoid CSynthFilter::ReconnectWithNewFormat(void) \r\n{\r\n    // The caller must hold the state lock because this\r\n    // function calls IsConnected().\r\n    ASSERT(CritCheckIn(pStateLock()));\r\n\r\n    // The synth filter's only has one pin.  The pin is an output pin.\r\n    CDynamicSourceStream* pOutputPin = (CDynamicSourceStream*)GetPin(0);\r\n\r\n    if( pOutputPin->IsConnected() ) {\r\n        pOutputPin->OutputPinNeedsToBeReconnected();\r\n    }\r\n}\r\n\r\n\r\n\r\n//\r\n// get_BitsPerSample\r\n//\r\nSTDMETHODIMP CSynthFilter::get_BitsPerSample(int *BitsPerSample) \r\n{\r\n    HRESULT hr = m_Synth->get_BitsPerSample(BitsPerSample);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_BitsPerSample: %d\"), *BitsPerSample));\r\n    return hr;\r\n}\r\n\r\n\r\n\r\n//\r\n// get_SamplesPerSec\r\n//\r\nSTDMETHODIMP CSynthFilter::get_SamplesPerSec(int *SamplesPerSec) \r\n{\r\n    HRESULT hr = m_Synth->get_SamplesPerSec(SamplesPerSec);\r\n    \r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_SamplesPerSec: %d\"), *SamplesPerSec));\r\n    return hr;\r\n}\r\n\r\n\r\n\r\n//\r\n// get_Amplitude\r\n//\r\nSTDMETHODIMP CSynthFilter::get_Amplitude(int *Amplitude) \r\n{\r\n    m_Synth->get_Amplitude (Amplitude);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_Amplitude: %d\"), *Amplitude));\r\n    return NOERROR;\r\n}\r\n\r\n\r\n\r\n//\r\n// get_SweepRange\r\n//\r\nSTDMETHODIMP CSynthFilter::get_SweepRange(int *SweepStart, int *SweepEnd) \r\n{\r\n    m_Synth->get_SweepRange (SweepStart, SweepEnd);\r\n\r\n    DbgLog((LOG_TRACE, 3, TEXT(\"get_SweepStart: %d %d\"), *SweepStart, *SweepEnd));\r\n    return NOERROR;\r\n}\r\n\r\n\r\nSTDMETHODIMP CSynthFilter::get_OutputFormat(SYNTH_OUTPUT_FORMAT* pOutputFormat) \r\n{\r\n    HRESULT hr = m_Synth->get_OutputFormat(pOutputFormat);\r\n    if (FAILED(hr)) {\r\n        return hr;\r\n    }\r\n\r\n    return S_OK;\r\n}\r\n\r\nvoid CSynthStream::DerivePCMFormatFromADPCMFormatStructure(const WAVEFORMATEX& wfexADPCM, \r\n                                                           WAVEFORMATEX* pwfexPCM)\r\n{\r\n    ASSERT(pwfexPCM);\r\n    if (!pwfexPCM)\r\n        return;\r\n\r\n    pwfexPCM->wFormatTag = WAVE_FORMAT_PCM; \r\n    pwfexPCM->wBitsPerSample = 16;\r\n    pwfexPCM->cbSize = 0;\r\n\r\n    pwfexPCM->nChannels = wfexADPCM.nChannels;\r\n    pwfexPCM->nSamplesPerSec = wfexADPCM.nSamplesPerSec;\r\n\r\n    pwfexPCM->nBlockAlign = (WORD)((pwfexPCM->nChannels * pwfexPCM->wBitsPerSample) / BITS_PER_BYTE);\r\n    pwfexPCM->nAvgBytesPerSec = pwfexPCM->nBlockAlign * pwfexPCM->nSamplesPerSec;\r\n}\r\n\r\n\r\nvoid CAudioSynth::CalcCache(const WAVEFORMATEX& wfex)\r\n{\r\n    switch(m_iWaveform)\r\n    {\r\n        case WAVE_SINE:\r\n            CalcCacheSine(wfex);\r\n            break;\r\n\r\n        case WAVE_SQUARE:\r\n            CalcCacheSquare(wfex);\r\n            break;\r\n\r\n        case WAVE_SAWTOOTH:\r\n            CalcCacheSawtooth(wfex);\r\n            break;\r\n\r\n        case WAVE_SINESWEEP:\r\n            CalcCacheSweep(wfex);\r\n            break;\r\n    }\r\n}\r\n\r\n\r\n//\r\n// CalcCacheSine\r\n//\r\n//\r\nvoid CAudioSynth::CalcCacheSine(const WAVEFORMATEX& wfex)\r\n{\r\n    int i;\r\n    double d;\r\n    double amplitude;\r\n    double FTwoPIDivSpS;\r\n\r\n    amplitude = ((wfex.wBitsPerSample == 8) ? 127 : 32767 ) * m_iAmplitude / 100;\r\n\r\n    FTwoPIDivSpS = m_iFrequency * TWOPI / wfex.nSamplesPerSec;\r\n\r\n    m_iWaveCacheIndex = 0;\r\n    m_iCurrentSample = 0;\r\n\r\n    if(wfex.wBitsPerSample == 8)\r\n    {\r\n        BYTE * pB = m_bWaveCache;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            d = FTwoPIDivSpS * i;\r\n            *pB++ = (BYTE) ((sin(d) * amplitude) + 128);\r\n        }\r\n    }\r\n    else\r\n    {\r\n        PWORD pW = (PWORD) m_wWaveCache;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            d = FTwoPIDivSpS * i;\r\n            *pW++ = (WORD) (sin(d) * amplitude);\r\n        }\r\n    }\r\n}\r\n\r\n\r\n//\r\n// CalcCacheSquare\r\n//\r\n//\r\nvoid CAudioSynth::CalcCacheSquare(const WAVEFORMATEX& wfex)\r\n{\r\n    int i;\r\n    double d;\r\n    double FTwoPIDivSpS;\r\n    BYTE b0, b1;\r\n    WORD w0, w1;\r\n\r\n    b0 = (BYTE) (128 - (127 * m_iAmplitude / 100));\r\n    b1 = (BYTE) (128 + (127 * m_iAmplitude / 100));\r\n    w0 = (WORD) (32767. * m_iAmplitude / 100);\r\n    w1 = (WORD) - (32767. * m_iAmplitude / 100);\r\n\r\n    FTwoPIDivSpS = m_iFrequency * TWOPI / wfex.nSamplesPerSec;\r\n\r\n    m_iWaveCacheIndex = 0;\r\n    m_iCurrentSample = 0;\r\n\r\n    if(wfex.wBitsPerSample == 8)\r\n    {\r\n        BYTE * pB = m_bWaveCache;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            d = FTwoPIDivSpS * i;\r\n            *pB++ = (BYTE) ((sin(d) >= 0) ? b1 : b0);\r\n        }\r\n    }\r\n    else\r\n    {\r\n        PWORD pW = (PWORD) m_wWaveCache;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            d = FTwoPIDivSpS * i;\r\n            *pW++ = (WORD) ((sin(d) >= 0) ? w1 : w0);\r\n        }\r\n    }\r\n}\r\n\r\n\r\n//\r\n// CalcCacheSawtooth\r\n//\r\nvoid CAudioSynth::CalcCacheSawtooth(const WAVEFORMATEX& wfex)\r\n{\r\n    int i;\r\n    double d;\r\n    double amplitude;\r\n    double FTwoPIDivSpS;\r\n    double step;\r\n    double curstep=0;\r\n    BOOL fLastWasNeg = TRUE;\r\n    BOOL fPositive;\r\n\r\n    amplitude = ((wfex.wBitsPerSample == 8) ? 255 : 65535 )\r\n        * m_iAmplitude / 100;\r\n\r\n    FTwoPIDivSpS = m_iFrequency * TWOPI / wfex.nSamplesPerSec;\r\n    step = amplitude * m_iFrequency / wfex.nSamplesPerSec;\r\n\r\n    m_iWaveCacheIndex = 0;\r\n    m_iCurrentSample = 0;\r\n\r\n    BYTE * pB = m_bWaveCache;\r\n    PWORD pW = (PWORD) m_wWaveCache;\r\n\r\n    for(i = 0; i < m_iWaveCacheSize; i++)\r\n    {\r\n        d = FTwoPIDivSpS * i;\r\n\r\n        // OneShot triggered on positive zero crossing\r\n        fPositive = (sin(d) >= 0);\r\n\r\n        if(fLastWasNeg && fPositive)\r\n        {\r\n            if(wfex.wBitsPerSample == 8)\r\n                curstep = 128 - amplitude / 2;\r\n            else\r\n                curstep = 32768 - amplitude / 2;\r\n        }\r\n        fLastWasNeg = !fPositive;\r\n\r\n        if(wfex.wBitsPerSample == 8)\r\n            *pB++ = (BYTE) curstep;\r\n        else\r\n            *pW++ = (WORD) (-32767 + curstep);\r\n\r\n        curstep += step;\r\n    }\r\n}\r\n\r\n\r\n//\r\n// CalcCacheSweep\r\n//\r\nvoid CAudioSynth::CalcCacheSweep(const WAVEFORMATEX& wfex)\r\n{\r\n    int i;\r\n    double d;\r\n    double amplitude;\r\n    double FTwoPIDivSpS;\r\n    double CurrentFreq;\r\n    double DeltaFreq;\r\n\r\n    amplitude = ((wfex.wBitsPerSample == 8) ? 127 : 32767 ) * m_iAmplitude / 100;\r\n\r\n    DeltaFreq = ((double) m_iSweepEnd - m_iSweepStart) / m_iWaveCacheSize;\r\n    CurrentFreq = m_iSweepStart;\r\n\r\n    m_iWaveCacheIndex = 0;\r\n    m_iCurrentSample = 0;\r\n\r\n    if(wfex.wBitsPerSample == 8)\r\n    {\r\n        BYTE * pB = m_bWaveCache;\r\n        d = 0.0;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            FTwoPIDivSpS = (int) CurrentFreq * TWOPI / wfex.nSamplesPerSec;\r\n            CurrentFreq += DeltaFreq;\r\n            d += FTwoPIDivSpS;\r\n            *pB++ = (BYTE) ((sin(d) * amplitude) + 128);\r\n        }\r\n    }\r\n    else\r\n    {\r\n        PWORD pW = (PWORD) m_wWaveCache;\r\n        d = 0.0;\r\n\r\n        for(i = 0; i < m_iWaveCacheSize; i++)\r\n        {\r\n            FTwoPIDivSpS = (int) CurrentFreq * TWOPI / wfex.nSamplesPerSec;\r\n            CurrentFreq += DeltaFreq;\r\n            d += FTwoPIDivSpS;\r\n            *pW++ = (WORD) (sin(d) * amplitude);\r\n        }\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "source_code/virtual audio output sniffer.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 11.00\r\n# Visual C++ Express 2010\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"audio_sniffer\", \"acam\\acam.vcxproj\", \"{B6830EAD-C98E-490D-8999-CAA246788BF7}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Win32 = Debug|Win32\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tRelease|Win32 = Release|Win32\r\n\t\tRelease|x64 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Debug|Win32.ActiveCfg = Debug|Win32\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Debug|Win32.Build.0 = Debug|Win32\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Release|Win32.ActiveCfg = Release|Win32\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Release|Win32.Build.0 = Release|Win32\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{B6830EAD-C98E-490D-8999-CAA246788BF7}.Release|x64.Build.0 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  }
]