Sometimes it is necessary to link to a DLL that might not be installed on the users system. Usually this is to add support for new features, but to still gracefully handle the case where it is not available. For eample, you might want to use Direct! "" on #indows $, but fall back to Direct! % on #indows !&. 'his is generally (uite straightforward to achieve by using LoadLibrary and GetProcAddress at runtime to load the re(uired library if its available) 'his process becomes somewhat more complicated when using a side*by*side DLL, due to the way they are loaded. Linking to SS DLLs re(uires you to include an entry in the application manifest which allows the SS loader to find the right DLL. 'o use #indows +ista style common controls, for eample, you have to insert the following as a dependent assembly into your manifest) ,f the SS DLL is not present on the users machine then the application will fail to start. -owever, you cant simply remove it and try to load it at runtime instead, as then the call to LoadLibrary wont be able to find it. 'he solution to this catch*.. re(uires you to embed a separate manifest in the application resources which references the assembly, modify the activation contet to load this manifest at runtime, then finally try to load the DLL. For the sake of clarity, ,ve omitted any error checking in the code below. ,f the DLL isnt available, CreateActCtx will return INVALID_HANDLE_VALUE and GetLastError() will return ERROR_SXS_CAN_GEN_ACCX. ,f the activation contet is successfully created then it is simply a case of activating it and loading the library as normal) Chris Spencer ! " # $ % & ' ( HMODULE d#d!! * LoadLibrary+(L,d#d!!-d..,)/ if (d#d!!) 0 auto D#D!!CreateDe1ice_ * reinterpret_cast2decltype(3D#D!!CreateDe1ice)4( GetProcAddress(d#d!!5 ,D#D!!CreateDe1ice,))/ 66 --- 7 ! " # $ % & ' 2assemblyIdentity ty8e*,9i:#", :a;e*,<icroso=t-+i:do9s-Co;;o:>Co:tro.s, 1ersio:*,&-?-?-?, 8rocessorArc@itectAre*,x(&, 8Ab.icBeyoCe:*,&%D%b&$!$$cc=!d=, .a:EAaEe*,F,64 ! " # $ % & ' ( D ACCX+ actctx * 0 ? 7/ actctx-cbSiGe * sizeof(actctx)/ actctx-d9H.aEs * ACCX_HLAG_RESOURCE_NA<E_VALID I ACCX_HLAG_H<ODULE_VALID/ actctx-.8SoArce * ;odA.ePat@/ actctx-.8ResoArceNa;e * ;a:i=est/ actctx-@<odA.e * ;odA.e/ HANDLE acti1atio:Co:text * CreateActCtx+(3actctx)/ ! " ULONG_P! cooCie/ Acti1ateActCtx(acti1atio:Co:text5 3cooCie) Chris Spencer http://cwspencer.co.uk/blog/ 1 of 14 6/1/2014 8:13 PM 'he activation contet is no longer re(uired after loading the DLL, so its a good idea to clean up after yourself) 'his techni(ue is also useful if you want to support multiple different versions of the same library by including a separate manifest for each version of the library you support and trying each of them in order at runtime until one of them works. / complete eample which attempts to load three different versions of the 0icrosoft Flight Simulator Sim1onnect SD2 can be downloaded here) Sim1onnectLoader.3ip. Posted in programming | Comments Off Ineffective small functor optimisation in Visual Studio 2012 Posted on February 2, 2014 by Chris Spencer 144"" introduced the stdJJ=A:ctio: class, which acts as a generic wrapper around something callable 5a functor6. /mong other things, these are very useful for callback functions, as they allow non*static member functions to be used, which isnt possible with stock function pointers without some wrangling. / common idiom is to use an opa(ue contet pointer along with a static member function that calls a non*static member function to do the actual work) stdJJ=A:ctio: simplifies this as it can hold any functor, meaning it can hold a member function pointer along with a pointer to the associated ob7ect) # .ibrary * LoadLibrary+(L,KoArLib-d..,)/ ! " Deacti1ateActCtx(?5 cooCie)/ Re.easeActCtx(acti1atio:Co:text)/ ! " # $ % & ' ( D !? !! !" !# !$ !% !& !' !( !D "? "! "" "# "$ "% "& "oid .o:EO8eratio:("oid (Fca..bacC)("oid Fco:text)5 "oid Fco:text) 0 66 Do so;e 9orC t@e: i:1oCe t@e ca..bacC =A:ctio: ca..bacC(co:text)/ 7
class <yC.ass 0 publicJ "oid doSo;et@i:E() 0 .o:EO8eratio:(o:Ca..bacC5 t#is)/ 7
class <yC.ass Chris Spencer http://cwspencer.co.uk/blog/ 2 of 14 6/1/2014 8:13 PM #hen using stdJJbi:d, arguments can be bound, meaning their value is fied when the functor is created, or unbound using placeholders, meaning their value is set when the functor is invoked) ,mplementations of stdJJ=A:ctio: will typically optimise the common case of small functors 5such as a member function pointer and an ob7ect, which would typically take 8 bytes on a 9.*bit architecture6 by allocating them on the stack, while larger functors will go on the heap, which is where the point of this post lies. 'he +isual Studio .:". implementation allocates "; bytes of stack space for small functors, which should be plenty of space for most use cases. Unfortunately, there is a lot of waste in the implementation. 'he functor is wrapped in a _HA:c_i;8. ob7ect, which, in addition to holding the functor, has an allocator and a base class with virtual methods. 'he virtual methods add < bytes to the class for the virtual function pointer table, and the allocator, although it is an empty stdJJa..ocator, must be addressable, and due to alignment re(uirements adds another < bytes. 'his means the "; bytes of space available for the small functor optimisation is now cut down to 7ust 8 bytes. 8 bytes is of course enough to hold a member function and ob7ect pointer, but we now run into an issue with the implementation of stdJJbi:d. 'he +isual Studio .:". implementation of stdJJbi:d uses < bytes for every placeholder. 'his means the result of bi:d(3<yC.assJJo:Ca..bacC5 t@is5 _!), for instance, takes ". bytes, which, with the 8 bytes of overhead in stdJJ=A:ctio:, means it is too big for the small functor optimisation and will end up on the heap. 'his effectively means the small functor optimisation will only work for member functions that have no arguments at all. ( D !? !! !" !# !$ !% !& !' !( !D "? 0 publicJ "oid doSo;et@i:E() 0 .o:EO8eratio:(bi:d(3<yC.assJJo:Ca..bacC5 t#is))/ 7
class <yC.ass 0 publicJ "oid doSo;et@i:E() 0 .o:EO8eratio:(bi:d(3<yC.assJJo:Ca..bacC5 t#is5 66 @is arEA;e:t is A:boA:d as it is Asi:E 66 stdJJ8.ace@o.dersJJ_! _!5 66 @is arEA;e:t is boA:d a:d t@e 1a.Ae is 66 stored i:side t@e =A:ctor obLect $%&))/ 7
pri"ateJ "oid o:Ca..bacC(int x5 int y) 0 66 x ** !"# 66 y ** $%& 7 7/ Chris Spencer http://cwspencer.co.uk/blog/ 3 of 14 6/1/2014 8:13 PM 'he =oost implementation fares much better in comparison. boostJJ=A:ctio: allocates .< bytes on the stack for functors, and it does not wrap the functor in anything, meaning the full space is available. /dditionally, placeholders in boostJJbi:d take no space at all. 'his means there is a full "; bytes available for bound arguments before the functor will be forced onto heap in boostJJ=A:ctio:. 'he small functor optimisation can be important in applications that make heavy use of functors as it will avoid a large number of small heap allocations. /s such, , would recommend sticking to the =oost versions if you are targeting +isual Studio .:".. Note: 'he above is based on my analysis of the code in =oost and the +isual Studio .:". headers and may contain errors. &lease leave a comment if you think ,ve made a mistake> ,t also does not reflect behaviour in the ;<*bit build, which , imagine would be similar, but havent tested. ,d be interested to hear if its implemented any differently in +isual Studio .:"9. Posted in programming | 5 Comments Getting useful C++ exception information from Visual Studio Posted on October 5, 2012 by Chris Spencer 'rying to get useful information about a 144 eception from a crash dump in +isual Studio is often an eercise in frustration, with useless dialogs like this being typical) ,n this post ,m going to present two ways of getting more information from the eception. 'he second method is more reliable and easier to use, but also re(uires a minor code change. 'he first thing to do is find the _Cxx@ro9Exce8tio: frame in the stack trace. 'his contains the information you need to find the eception ob7ect. Chris Spencer http://cwspencer.co.uk/blog/ 4 of 14 6/1/2014 8:13 PM ,n the local variables window navigate to @isExce8tio: 8ara;s 8Exce8tio:ObLect. 'his carries the pointer to the ob7ect that was thrown. ?etting the type of the eception ob7ect may take a bit of guesswork, but can probably be determined by looking at 8@ro9I:=o, or at where the eception was thrown in the code. @therwise, the stdJJexce8tio: base class is usually fine anyway. ,n this case it is stdJJsyste;_error. 1opy the address into the watch window and add an appropriate cast. Aou now have all the eception information you need> Aou may need to switch to the frame in which the eception was thrown in your application for the cast to work, otherwise the debugger wont know about the type you specified. #e can see here that we failed to open some super*important file with an error code of 9, which we know means the file doesnt eist. Unfortunately, sometimes you might find your eception information has been optimised away) Chris Spencer http://cwspencer.co.uk/blog/ 5 of 14 6/1/2014 8:13 PM ,f this happens youre pretty much out of luck for any eisting crash dumps, but if you switch to method two then future dumps should be more useful. 'he second method involves installing your own unhandled eception filter and forcing the process to eit immediately, while still preserving the eception information. , generally prefer this method because it is more reliable and easier to work with. First thing to do is define your unhandled eception filter) LONG WINAPI unhandledExceptionFilter(EXCEPTION_POINTERS *exInfo) { RaiseFailFastException(exInfo->ExceptionRecord, exInfo->ContextRecord, 0); return EXCEPTION_CONTINUE_SEARCH; // Not reached } int main() { SetUnhandledExceptionFilter(unhandledExceptionFilter); // ... } -ere we use RaiseHai.HastExce8tio: to kill the process immediately and invoke #indows Brror Ceporting to create your crash dump. 'his bypasses whatever the 1 runtime does which causes it to lose your eception information and you get a much more useful dialog when you enter the debugger) 'his time weve got both the type of the eception and its address 5which in this case is ?x??"(HD#(6. &ut this in your watch window in the same way as described before and you will have your eception ob7ect> Bonus: Aou can get #BC to generate full crash dumps when your program crashes and you dont have a debugger attached by creating the D+ORD registry key HBEK_LOCAL_<ACHINEMSOH+AREM<icroso=tM+i:do9sM+i:do9s Error Re8orti:EMLoca.DA;8sMDA;8y8e and setting it to " 5for mini dumps6 or . 5for full dumps6. 'his will create a dump file in NLOCALAPPDAANMCras@DA;8s when your program crashes which you can import into +isual Studio. 'his is particularly useful when you are testing on someone elses machine where you cant debug directly. Posted in programming | 1 Comment Synchronising Audio Generation and Consumption Posted on November 30, 2011 by Chris Spencer Chris Spencer http://cwspencer.co.uk/blog/ 6 of 14 6/1/2014 8:13 PM /s my final year university pro7ect , am building an emulator and source*level debugger for the ?ame =oy and ?ame =oy 1olorD todays post is about the troubles , have had whilst emulating the sound system for the ?ame =oy. 'he technical details about how the ?ame =oy sound hardware works is not important for this postD the problem is with getting the audio after it has been emulated to the sound card. /udio buffer underflows and overflows have been causing me much frustration ever since , wrote the initial implementation a few months back, as each time it happens it creates an audible skip in the playback. , initially 7ust assumed it was because the SDL audio library re(uests audio from a separate thread 5,m still not convinced this is a good idea, even though it turned out not to be the cause of the problem6. =ecause of this , moved the sound generation code into the audio thread so it was generated on demand. 'his seemed to to work pretty well, mainly because the ?ame =oy sound system is almost completely isolated from everything elseD the game 7ust sets a couple of registers indicating what tone it wants to play then the sound hardware goes away and generates the appropriate tones. @f course, as is (uite typical with old consoles, games like to push the hardware to the limit, which means timings must be etremely accurate in order for an emulator to work correctly. /s it turns out, in &okemon Aellow when the game plays the E&ikachu sound, the game forces the sound hardware to play the sample*based sound 5something which it is not very good at as standard6 by switching the sound on and off as fast as the 1&U will allow. Faturally this doesnt work at all when the sound emulation thread is only getting switched in every few hundred milliseconds, so , was forced to bring the sound emulation back into the main thread for the sound to be emulated correctly. /nd so the skipping came back with itG Still convinced that the threading was the problem , decided to rebuild the sound emulation on top of 0icrosofts #/S/&,. Fot only is #/S/&, closer to the hardware than higher level abstractions like SDL, meaning reduced latency and better (uality, but, crucially, it can all run in the same thread. So after spending several hours writing a #/S/&, backend that ended up being five times longer than the SDL backend 5it wouldnt be a 0icrosoft /&, if it wasnt significantly more complicated than everything else6, it was still skippingG Fot impressed. /fter this , focused more on how fast the samples were actually being generated versus how fast they were being consumed. /fter adding a bit of instrumentation code , found that the samples were being generated about .:: -3 too slowly. #hoops. , should point at here that , had two synchronisation timers running in parallel in my emulator) a simple idle loop that ran every frame to keep from the emulator running too fast, and the audio timer which the operating systemHaudio hardware uses to re(uest samples at the correct rate. , fied up the idle loop timer and got it generating the sound at eactly the right rate 4H* " -3. 'his fied the problem to a large etent, but it was skipping much more than , would like. ,ts about now that it hit me that the solution had been staring me in the face the entire time) use only one timer. 'he audio timer is re(uired to make any sound, so the idle loop timer had to go. ,nstead , replaced it with a callback in the audio backend which is called at a fied fre(uency derived from the audio clock based on when it re(uests new sound data. 'he sound samples could now be generated at eactly the rate they were re(uired and overflows and underflows simply stopped happening. , still opted to keep the #/S/&, backend because the SDL backend still seems to skip periodically, but even with SDL the problem is basically gone. ,ve put this here in the hopes it might be useful to someoneD , know , had trouble finding any useful information from my searches. Posted in programming | Comments Off Chris Spencer http://cwspencer.co.uk/blog/ 7 of 14 6/1/2014 8:13 PM The Ambiguity of Flight Plans Posted on August 26, 2011 by Chris Spencer Some time ago , wrote a utility to convert a flight plan route into a series of waypoints so it could be used by other applications. @n the face of it, this seems like a pretty simple taskD all you need to do is convert something like this) EGLL BUZAD T420 WELIN EGBB ,nto this) EGLL BUZAD OLNEY WELIN EGBB $"? here is an airwayD all we need to do is find the waypoints on the airway between OUPAD and +ELIN. Unfortunately, it turns out flight plan routes are actually (uite ambiguous. For eample, you cant be certain whether $"? is the name of an airway, or if it is a waypoint that should be directly flown to. ,n this case its pretty easy as there are no waypoints named $"?, so it must be an airway. @ften times, however, there will be many waypoints and airways going by the same name throughout the world, so you 7ust have to make a best guess based on the surrounding contet. 0uch tweaking was necessary in order to get it to a state where it wouldnt re7ect valid routes as invalid. / particularly memorable issue , had was with this route, purely because it was the only route in the large test set , had which had the problem) EGPH TLA N864 DCS [...] Decoded, this means fly from Bdinburgh /irport via a 'alla S,D to LA, then follow the N(&$ airway to DCS. , dont consider S,Ds while parsing as there is usually more than one with the same endpointD instead , 7ust take the waypoint with that name closest to the airport then continue from there. -owever, for some reason with this particular route , was getting errors saying it couldnt find N(&$ after LA. /s it turns out there is an FD= with the same name in the area, and as it happens the FD= is :." F0 closer to the airport than the +@C to which the airway is attached. 'his issue forced me to change the logic for handling direct routings such that it will look at all the potential waypoints for an attached airway with the name of the following token before giving up and 7ust using the closest available. Posted in aviation, programming | Comments Off Back Online Posted on August 22, 2011 by Chris Spencer Finally, after a long period of downtime, , am back online. =ack when the site was first set up it was hosted for free by a friend of mine in echange for some programming help with 144. Unfortunately, , made the mistake of allowing said friend to register the domain in his name. Some time later he closed his hosting down, and , was stuck with a domain , couldnt use and didnt actually own. , tried to get him to transfer the domain ownership to me, but he was unable to do so for whatever reason, and he was always very difficult to get hold of, so , pretty much gave up. Chris Spencer http://cwspencer.co.uk/blog/ 8 of 14 6/1/2014 8:13 PM -owever, the other day , checked the status of the domain on a which and discovered it had epired and was free to re*register, which was weird because he claimed to have re*registered the domain when attempting to transfer ownership. =ut regardless, , am finally in control of my own domain and have got a +&S set up with !,L@, at the recommendation of another friend. Luckily , had a backup of the #ord&ress database from before the server went down, and , managed to find most of the uploaded media files still lying around on my computer, so not too much was lost. , had a number of options for which Linu distributions could be pre*installed, which basically boiled down to the only two , am familiar with) 1ent@S and ?entoo. , initially set up ?entooD however, after a couple of failed kernel upgrades , gave up and installed 1ent@S. 'he problem is that working on it remotely, youre basically stuck if the system fails to boot. &erhaps for the best anywayD ,m more familiar with locking down 1ent@S from the ecellent ?uide to the Secure 1onfiguration of Ced -at Bnterprise Linu I produced by the FS/ which , have used to great effect at work. Setting up =,FD was an interesting challenge, as , have never done anything with DFS before. /n unusual aspect of !,L@ is that they dont provide nameservers, so you have to set up your own, but that raises the (uestion) how does one resolve the nameserver :s!-c9s8e:cer-co-AC when trying to resolve c9s8e:cer-co-ACJ 'urns out that is achieved with the help of so called Kglue recordsL. 'he ,& address of the name server is stored in a glue record on the -co-AC top*level domain. Fow when someone needs to resolve c9s8e:cer-co-AC, they use the glue record to resolve :s!-c9s8e:cer-co-AC to D%-!'"-"#(-D! and subse(uently (uery my =,FD server to resolve c9s8e:cer-co-AC, which of course also comes out to D%-!'"-"#(-D! as everything is running on the same server. Posted in linux, self | Comments Off Homebrew Earpiece for the Yaesu FT-60 Posted on August 17, 2010 by Chris Spencer ,m going to the =ournemouth /ir Festival this week, and of course will be bringing my -' for that etra /'1 goodness. Unfortunately though, the Aaesu F'*;: doesnt have a normal headphones socket. ,t does have a 9.Imm 7ack socket, but it has four contacts, and plugging in a normal three contact connector grounds the &''. Fo good. , checked the manual, and it seems , need the Aaesu 0-*9$/<=. , looked at various stores online and the cheapest , could find it for was about M.I. Fo thanksD its a cheap earphone with an abnormal connector. So of course , built my own. , bought a four pole 7ack from 0aplin 5N';I+6 for M., and some el cheapo earphones for M;, chopped off the connector, ripped off the right earpiece and soldered on the new connector. ,t works perfectly and was a third of the price. , call that a successful mission. Posted in amateur radio, elecronics | Comments Off PCTransceiver Connection for Data Modes Posted on August 8, 2010 by Chris Spencer ,ve wanted to properly connect my radio to my &1 for some time, enabling me to use data modes. , figured instead of getting a C,?blaster ,d build my ownD its a fairly simple circuit. , spent a few days designing the circuit with the assistance of a couple of websites.O". #0.Us Sound 1ard ,nterfacing SchemesP O.. /?#&B DocumentationP 'his is what , came up with) Chris Spencer http://cwspencer.co.uk/blog/ 9 of 14 6/1/2014 8:13 PM 'his is actually four electrically separate circuits. 'he computer side is completely isolated from the radio side to prevent a ground loop from distorting the signal. , will eplain each section of the circuit below. 0ost 5if not all6 amateur radio data mode applications have an option of activating the C'S line on a serial port when transmittingD this is used to activate the &'' circuit on the rig. /n opto*isolator is used to isolate the two sides of the circuit. 'his consists of an LBD and a phototransistor. #hen current flows through the LBD, current is allowed to flow through the transistor, grounding the &'' line and activating the transmitter. / "..kQ resistor is used to reduce the current reaching the LBDD the CS*.9. specification allows for up to .I+, which is too much for the diode. 'he D" diode acts as a shunt. #hen the C'S line is Eoff, it can be up to *.I+, which would damage the LBD in the opto*isolator if allowed to flow through it. ,nstead the current flows through the diode and out the C'S line. Fet is the transmit audio input. 'his is connected to the line out connection on the &1 sound card. 'his time an audio transformer is used to isolate the two circuits. 'he manual for my rig specifies the maimum input level is <:m+, so a resistive divider is necessary to reduce the R.+ input. , generated a sine wave in /udacity on my computer, set the volume to maimum, set my voltmeter to /1 mode and measured eactly ..I+ output. , used a resistive divider calculator to get the ;.k and "k resistor values. Finally the receive audio is pretty much the same as the transmit audio, ecept the voltage is R".I+, which is fine for the computer line in, so this doesnt need anything more. -aving designed and had checked the circuit , bought all the components from Farnell and got to work. /fter spending pretty much all day on it, , finally finished in the dwindling light) Chris Spencer http://cwspencer.co.uk/blog/ 10 of 14 6/1/2014 8:13 PM Bverything went perfectly on the first attemptD , didnt break anything, receive and transmit audio, and &'' all work perfectly. ,f you want to build your own , encourage you to check the links in the footnotes as they provide more detail. 'his circuit ought to work for any rig with a 0ini*D,F ; input 5usually marked Edata6. ,ll be happy to answer any (uestions if you leave a comment. Posted in amateur radio, elecronics | Comments Off Decoding the Yaesu FT-7800 Clone Data Format Posted on July 24, 2010 by Chris Spencer , bought a data cable for my radio a few days ago to connect it to my computer so , could program the memories more easily. , figured instead of buying the programming software ,d try to decode the data format the radio uses and write my own. ,ts 7ust more fun that way. 'he premise is simple enough, you need to make the application act like the radio and use clone mode to get the memory dump from the rig. @nce you have made your changes you do the same thing in reverse to send the data back. 'he transfer protocol is pretty simple, its essentially a file transfer protocol which always sends a file of the same si3e. Upon enabling clone transmit mode on the rig it sends the /S1,, string K/-:";SuSL. ,ts not clear eactly what this means so , 7ust check for it verbatim. Upon receiving this you send back an /12 character 5:T:;6 and the radio starts spewing out its data. 'he data is sent in ;< byte packets,O". ,ts not really a packet in the normal sense, theres no header data or anything like that, its 7ust a ;< byte block of raw data.P after each of which an /12 must be sent. 'he rig sends <%9 of packets to make a total of 9"II. bytes. /fter the last packet a single byte checksum is sent, which must be acknowledged. 'he 1hecksum Figuring out the checksum algorithm was something , wasnt really looking forward to, , figured it would be pretty hard to doD fortunately, this turned out not to be the case. , started by 7ust accumulating all the bytes in the data 5discarding overflow6. 'his didnt work, but after making several dumps with minor changes , noticed that the checksum was always at a certain offset from the accumulation of all the bytes. :T.9 less to be precise. #hats so special about :T.9 , have no idea, but it seems to work so it doesnt really matter. BchoG Something (uite frustrating , have come across with this is that the radio echoes everything sent to it, even if its off. , figure there must be a direct connection between the receive and transmit lines or something. ,t means , have to read back everything after , have 7ust written it. /nnoyingJ Aes, but not a huge issue really. Decoding the Data Decoding the data format is simply a case of changing what you are looking for on the radio then comparing the dumps to see where they differ. , decided to start by looking for the memory names in a he editor, theyre probably stored as /S1,, rightJ /pparently not. , couldnt find any /S1,, strings in the data at all. , changed the name of one of the memories and made another dump to see what was whatD it seems it uses its own ;*bit character set, which includes several weird glyphs that dont seem to map to any actual characters. , have Chris Spencer http://cwspencer.co.uk/blog/ 11 of 14 6/1/2014 8:13 PM decoded and included the character set in the table below. Dec Hex Oct Character Glyph : : : : " " " " . . . . 9 9 9 9 < < < < I I I I ; ; ; ; $ $ $ $ 8 8 ": 8 % % "" % ": / ". / "" = "9 = ". 1 "< 1 "9 D "I D "< B "; B "I F "$ F "; ": .: ? "$ "" ." - "8 ". .. , "% "9 .9 U .: "< .< 2 ." "I .I L .. "; .; 0 .9 "$ .$ F .< "8 9: @ .I "% 9" & .; "/ 9. N .$ "= 99 C .8 "1 9< S .% "D 9I ' 9: "B 9; U Chris Spencer http://cwspencer.co.uk/blog/ 12 of 14 6/1/2014 8:13 PM Dec Hex Oct Character Glyph 9" "F 9$ + 9. .: <: # 99 ." <" ! 9< .. <. A 9I .9 <9 V 9; .< << S& 9$ .I <I 98 .; <; 9% .$ <$ <: .8 I: S <" .% I" <. ./ I. <9 .= I9 << .1 I< <I .D II <; .B I; <$ .F I$ 4 <8 9: ;: <% 9" ;" * I: 9. ;. I" 99 ;9 H I. 9< ;< W I9 9I ;I I< 9; ;; II 9$ ;$ I; 98 $: I$ 9% $" I8 9/ $. I% 9= $9 ;: 91 $< ;" 9D $I ;. 9B $; Chris Spencer http://cwspencer.co.uk/blog/ 13 of 14 6/1/2014 8:13 PM Dec Hex Oct Character Glyph ;9 9F $$ X , have found the locations of a few other details, like the fre(uency and modulation mode, but , will leave those details for another day once , have got a better grasp of the format. Posted in amateur radio, programming | Comments Off SSTV Captures from the International Space Station Posted on July 15, 2010 by Chris Spencer 'oday and tomorrow 5Uuly "IY";6 the amateur radio station aboard the ,nternational Space Station is broadcasting SS'+ images on "<I.8:: 0-3.O". 0/,*$I activation planned for Uuly "I*";P , have managed to capture a couple of images as it passed over northern France today. Feither is a complete image sadly, but its still very cool. Something interesting that , havent eperienced before with receiving data from satellites was that a slight movement of the antenna could mean the difference between a strong signal and complete noiseD hence the thin lines of noise in the images. Fot sure why it should be different this time, normally the signal fading is (uite gradual. Posted in amateur radio | Tagged iss | Comments Off Chris Spencer Proudly powered by WordPress. Chris Spencer http://cwspencer.co.uk/blog/ 14 of 14 6/1/2014 8:13 PM