<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Christopher Sung</title>
	<atom:link href="https://chrissung.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://chrissung.com</link>
	<description>Musings on Engineering, Music, Family, and more</description>
	<lastBuildDate>Fri, 16 Jun 2023 20:23:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>

<image>
	<url>https://chrissung.com/wp-content/uploads/2017/03/a512x512.jpg?w=32</url>
	<title>Christopher Sung</title>
	<link>https://chrissung.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<cloud domain='chrissung.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<atom:link rel="search" type="application/opensearchdescription+xml" href="https://chrissung.com/osd.xml" title="Christopher Sung" />
	<atom:link rel='hub' href='https://chrissung.com/?pushpress=hub'/>
	<item>
		<title>Where is the Fox?</title>
		<link>https://chrissung.com/2023/06/16/where-is-the-fox/</link>
					<comments>https://chrissung.com/2023/06/16/where-is-the-fox/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Fri, 16 Jun 2023 19:52:47 +0000</pubDate>
				<category><![CDATA[Fatherhood]]></category>
		<category><![CDATA[Parenting]]></category>
		<guid isPermaLink="false">http://chrissung.com/?p=361</guid>

					<description><![CDATA[With Father&#8217;s Day upon us, I thought I&#8217;d share a story about a running joke in our family for the better part of our daughter&#8217;s childhood. One value I&#8217;ve tried to instill in my daughter over the years is to never understimate the importance of silliness in everyday life, nor to overlook it in one&#8217;s [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-large"><img width="1024" height="768" data-attachment-id="366" data-permalink="https://chrissung.com/2023/06/16/where-is-the-fox/the-fox-1/" data-orig-file="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp" data-orig-size="1400,1050" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="the-fox-1" data-image-description="" data-image-caption="" data-medium-file="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=300" data-large-file="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=660" src="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=1024" alt="" class="wp-image-366" srcset="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=1024 1024w, https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=150 150w, https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=300 300w, https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=768 768w, https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp 1400w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">The Fox</figcaption></figure></div>


<p>With Father&#8217;s Day upon us, I thought I&#8217;d share a story about a running joke in our family for the better part of our daughter&#8217;s childhood.</p>



<p>One value I&#8217;ve tried to instill in my daughter over the years is to never understimate the importance of <strong>silliness</strong> in everyday life, nor to overlook it in one&#8217;s daily interactions with friends, family, and co-workers. You never know what rituals might be born at any given time.</p>



<p>And similar to a new product feature, remember to document, document, document &#8212; photos, videos, diaries, blog posts, whatever suits your style. Your older self will thank you for reminding them of all the good stuff that happened along the way.</p>



<p>Happy Father&#8217;s Day!</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<a class="m-story" href="https://medium.com/@chrissung/where-is-the-fox-5dd9ca2170c9" target="_blank" data-width="660" data-border="1" data-collapsed="">View at Medium.com</a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2023/06/16/where-is-the-fox/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2023/06/the-fox-1.webp?w=1024" medium="image" />
	</item>
		<item>
		<title>Auth, Identity, and Single Sign-On in Practice</title>
		<link>https://chrissung.com/2023/05/30/auth-identity-and-single-sign-on-in-practice/</link>
					<comments>https://chrissung.com/2023/05/30/auth-identity-and-single-sign-on-in-practice/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Tue, 30 May 2023 14:19:53 +0000</pubDate>
				<category><![CDATA[software-engineering]]></category>
		<category><![CDATA[scalability]]></category>
		<category><![CDATA[software-design]]></category>
		<category><![CDATA[technology]]></category>
		<guid isPermaLink="false">http://chrissung.com/?p=340</guid>

					<description><![CDATA[Providing auth in your platforms can get really expensive really quickly, as your 3rd-party vendor costs grow as your user base grows. I had a chance to write about a great way to implement authentication, authorization, and SSO in a scalable and practical manner. I hope you like it. https://betterprogramming.pub/low-cost-auth-identity-and-single-sign-on-f8adad300025]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img src="https://chrissung.com/wp-content/uploads/2023/05/52ff4-08u1-6-m2uruwexsp.jpg" alt="" /></figure>



<p>Providing auth in your platforms can get really expensive really quickly, as your 3rd-party vendor costs grow as your user base grows. I had a chance to write about a great way to implement authentication, authorization, and SSO in a scalable and practical manner. I hope you like it.</p>



<p><a href="https://betterprogramming.pub/low-cost-auth-identity-and-single-sign-on-f8adad300025" rel="nofollow">https://betterprogramming.pub/low-cost-auth-identity-and-single-sign-on-f8adad300025</a></p>



<p></p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2023/05/30/auth-identity-and-single-sign-on-in-practice/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2023/05/52ff4-08u1-6-m2uruwexsp.jpg" medium="image" />
	</item>
		<item>
		<title>GraphQL Federation, Domain Autonomy, and You</title>
		<link>https://chrissung.com/2023/05/22/graphql-federation-domain-autonomy-and-you/</link>
					<comments>https://chrissung.com/2023/05/22/graphql-federation-domain-autonomy-and-you/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Mon, 22 May 2023 14:55:32 +0000</pubDate>
				<category><![CDATA[software-engineering]]></category>
		<category><![CDATA[distributed-systems]]></category>
		<category><![CDATA[graphql]]></category>
		<category><![CDATA[software-design]]></category>
		<category><![CDATA[system-design]]></category>
		<category><![CDATA[technology]]></category>
		<guid isPermaLink="false">http://chrissung.com/?p=331</guid>

					<description><![CDATA[Hello, hello. It&#8217;s been a while but I&#8217;m finally getting a chance to document some of my favorite engineering design patterns and tools adopted over the years, and how to leverage them in your own systems. First up is a great lever to pull when addressing issues of scalability and domain ownership in your growing [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img width="1024" height="573" data-attachment-id="332" data-permalink="https://chrissung.com/2023/05/22/graphql-federation-domain-autonomy-and-you/graphql-federation-midjourney/" data-orig-file="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png" data-orig-size="1456,816" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="graphql-federation-midjourney" data-image-description="" data-image-caption="" data-medium-file="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=300" data-large-file="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=660" src="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=1024" alt="" class="wp-image-332" srcset="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=1022 1022w, https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=150 150w, https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=300 300w, https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=768 768w, https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png 1456w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Federated GraphQL, as imagined by Midjourney</figcaption></figure>



<p>Hello, hello. It&#8217;s been a while but I&#8217;m finally getting a chance to document some of my favorite engineering design patterns and tools adopted over the years, and how to leverage them in your own systems.</p>



<p>First up is a great lever to pull when addressing issues of scalability and domain ownership in your growing platform: GraphQL Federation. I hope you like it. <br><br><a href="https://betterprogramming.pub/graphql-federation-for-cross-domain-bliss-fbbb8004f8f9">GraphQL Federation for Cross-domain Bliss</a><br><br></p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<a class="m-story" href="https://medium.com/@chrissung/graphql-federation-for-cross-domain-bliss-fbbb8004f8f9" target="_blank" data-width="660" data-border="1" data-collapsed="">View at Medium.com</a>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2023/05/22/graphql-federation-domain-autonomy-and-you/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2023/05/graphql-federation-midjourney.png?w=1024" medium="image" />
	</item>
		<item>
		<title>Reverse Video in iOS</title>
		<link>https://chrissung.com/2017/03/11/reverse-video-in-ios/</link>
					<comments>https://chrissung.com/2017/03/11/reverse-video-in-ios/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Sat, 11 Mar 2017 21:42:17 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mobile App Development]]></category>
		<category><![CDATA[AVFoundation]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Objective-C]]></category>
		<guid isPermaLink="false">http://chrissung.com/?p=295</guid>

					<description><![CDATA[When I started writing the video processing engine for what would become the BeatCam app, one of the aspects we wanted to control was the direction in which the video traveled, e.g. forward or reverse. Manipulating media in iOS involves the use of Apple&#8217;s AVFoundation library and its related classes that allow developers to read, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>When I started writing the video processing engine for what would become the <a href="https://itunes.apple.com/us/app/beatcam-make-great-videos-music-color-effects/id1060881144?mt=8">BeatCam app</a>, one of the aspects we wanted to control was the direction in which the video traveled, e.g. forward or reverse.  Manipulating media in iOS involves the use of <a href="https://developer.apple.com/av-foundation/">Apple&#8217;s AVFoundation library</a> and its related classes that allow developers to read, write, and process video and audio data for a variety of use cases, so that became the obvious place to start.</p>
<p>The premise was to able to script these behaviors dynamically and make them available for users to apply to their videos to create experiences like this:</p>
<div style="text-align:center;margin-bottom:2em;">
<div id="v-4APaG0K5-1" class="video-player" style="width:660px;height:660px">
<video id="v-4APaG0K5-1-video" width="660" height="660" poster="https://videos.files.wordpress.com/4APaG0K5/revex1_scruberthumbnail_0.jpg" controls="true" preload="metadata" dir="ltr" lang="en"><source src="https://videos.files.wordpress.com/4APaG0K5/revex1_std.mp4" type="video/mp4; codecs=&quot;avc1.64001E, mp4a.40.2&quot;" /><div><img alt="BeatCam AutoDance Example" src="https://videos.files.wordpress.com/4APaG0K5/revex1_scruberthumbnail_0.jpg" width="660" height="660" /></div><p>BeatCam AutoDance Example</p></video></div>
</div>
<p>For our needs, it wasn&#8217;t going to be possible to extract video frames in real-time in the order needed to convey reverse movement. The only possible solution involved the creation of a companion video file that contained a reverse ordering of the video frames of the original. Also, since BeatCam processes input audio sources using a completely different pipeline from the video, we could conveniently ignore any audio in the original and simply output a silent, reversed version of the original.</p>
<p>A nice solution to this problem is <a href="http://www.andyhin.com/post/5/reverse-video-avfoundation">outlined by Andy Hin</a> in which an AVAssetReader can be used to read the input frames and their corresponding timestamps.  One can keep an array of the frame buffers, and when it&#8217;s time to write them to file, you use the same original timestamps in order, but use frame data starting at the end of the frame array and append to the output in time descending order.</p>
<p>However, Andy&#8217;s actual implementation is geared more toward reversing short videos of 30s or less. Longer videos will cause memory usage to blow up since one can&#8217;t keep a large number of frames around in memory before starting to output to file. And in BeatCam, any video in your library or that you shoot with the camera is fair game, so any implementation would need to function independently of input video duration.</p>
<p>In addition, this processing within BeatCam needed to occur behind the scenes since the user could be occupied with other aspects of the UI, so it was imperative that it run in its own thread. And if this call was now asynchronous, then some kind of completion block or delegate callback would need to be implemented.</p>
<p>One possible solution to the memory issue is to perform an initial reconnaissance of the entire file with respect to timestamps and frames, to organize this data into an array of passes where each pass contains a maximum number of frames (in this case, 100), and to then process each pass by extracting just the frames in the given pass and writing to output.</p>
<p><strong>The Recon Stage</strong></p>
<pre>
// main array to hold presentation times
NSMutableArray *revSampleTimes = [[NSMutableArray alloc] init];

// now go through the reader output to get some recon on frame presentation times
CMSampleBufferRef sample;
int localCount = 0;
while((sample = [assetReaderOutput copyNextSampleBuffer])) {
  CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sample);
  NSValue *presentationValue = [NSValue valueWithBytes:&amp;presentationTime objCType:@encode(CMTime)];
  [revSampleTimes addObject:presentationValue];
  CFRelease(sample);
  
  localCount++;
}
</pre>
<p>This method works only because AVAssetReader has the ability to read from input file for a given time range with little cost in initial seek time to the beginning of the range. Thus we can use the array of input frame timestamps to create the main array of dictionaries that will define the passes.</p>
<p><strong>Creating the Array of Pass Info</strong></p>
<pre>
// each pass is defined by a time range which we can specify each time we re-init the asset reader
    
// array that holds the pass info
NSMutableArray *passDicts = [[NSMutableArray alloc] init];

NSValue *initEventValue = [revSampleTimes objectAtIndex:0];
CMTime initEventTime = [initEventValue CMTimeValue];

CMTime passStartTime = [initEventValue CMTimeValue];
CMTime passEndTime = [initEventValue CMTimeValue];

int timeStartIndex = -1;
int timeEndIndex = -1;
int frameStartIndex = -1;
int frameEndIndex = -1;

NSValue *timeEventValue, *frameEventValue;
NSValue *passStartValue, *passEndValue;
CMTime timeEventTime, frameEventTime;

int totalPasses = (int)ceil((float)revSampleTimes.count / (float)numSamplesInPass);

BOOL initNewPass = NO;
for (NSInteger i=0; i0) {
      passStartValue = [NSValue valueWithBytes:&amp;passStartTime objCType:@encode(CMTime)];
      passEndValue = [NSValue valueWithBytes:&amp;passEndTime objCType:@encode(CMTime)];
      NSDictionary *dict = @{
        @"passStartTime": passStartValue,
        @"passEndTime": passEndValue,
        @"timeStartIndex" : [NSNumber numberWithLong:timeStartIndex],
        @"timeEndIndex": [NSNumber numberWithLong:timeEndIndex],
        @"frameStartIndex" : [NSNumber numberWithLong:frameStartIndex],
        @"frameEndIndex": [NSNumber numberWithLong:frameEndIndex]
      };
      [passDicts addObject:dict];
    }
    initNewPass = YES;
  }
  
  // if new pass then init the main vars
  if (initNewPass) {
    passStartTime = timeEventTime;
    timeStartIndex = (int)i;
    frameStartIndex = (int)(revSampleTimes.count - 1 - i);
    initNewPass = NO;
  }
}

// handle last pass
if ((passDicts.count &lt; totalPasses) || revSampleTimes.count%numSamplesInPass != 0) {
  passStartValue = [NSValue valueWithBytes:&amp;passStartTime objCType:@encode(CMTime)];
  passEndValue = [NSValue valueWithBytes:&amp;passEndTime objCType:@encode(CMTime)];
  NSDictionary *dict = @{
    @&quot;passStartTime&quot;: passStartValue,
    @&quot;passEndTime&quot;: passEndValue,
    @&quot;timeStartIndex&quot; : [NSNumber numberWithLong:timeStartIndex],
    @&quot;timeEndIndex&quot;: [NSNumber numberWithLong:timeEndIndex],
    @&quot;frameStartIndex&quot; : [NSNumber numberWithLong:frameStartIndex],
    @&quot;frameEndIndex&quot;: [NSNumber numberWithLong:frameEndIndex]
  };
  [passDicts addObject:dict];
}
</pre>
<p>For each pass, a new AVAssetReader is initialized and the time range to be read is set to the subset of frames relating to the current pass.</p>
<p>Passes are read in reverse order, e.g. last pass to first, and in each pass, frames are written from the end of the pass to the start, which effectively writes all frames in the file in reverse order with capped memory usage (the number of frames in a pass) regardless of the length of the input video.  This means the last pass will contain the total number of frames modulo the number of frames per pass. For example, if the input video has 456 total frames, and we are processing 100 frames per pass, then we will have 5 total passes, with the last pass containing 56 frames. This last pass will be the first one written to output, followed by 4 more of 100 frames a piece.</p>
<p><strong>Using the Pass Array to Write the Output</strong></p>
<pre>
int frameCount = 0; // master frame counter
int fpsInt = (int)(fps + 0.5);

// now go through the read passes and write to output
for (NSInteger z=passDicts.count-1; z&gt;=0; z--) {
  NSDictionary *dict = [passDicts objectAtIndex:z];
  
  passStartValue = dict[@"passStartTime"];
  passStartTime = [passStartValue CMTimeValue];
  
  passEndValue = dict[@"passEndTime"];
  passEndTime = [passEndValue CMTimeValue];
  
  CMTime passDuration = CMTimeSubtract(passEndTime, passStartTime);
  
  int timeStartIx = (int)[dict[@"timeStartIndex"] longValue];
  int timeEndIx = (int)[dict[@"timeEndIndex"] longValue];
  
  int frameStartIx = (int)[dict[@"frameStartIndex"] longValue];
  int frameEndIx = (int)[dict[@"frameEndIndex"] longValue];
  
  CMTimeRange localRange = CMTimeRangeMake(passStartTime,passDuration);
  NSValue *localRangeValue = [NSValue valueWithBytes:&amp;localRange objCType:@encode(CMTimeRange)];
  NSMutableArray *localRanges = [[NSMutableArray alloc] init];
  [localRanges addObject:localRangeValue];
  
  // reset the reader to the range of the pass
  [assetReaderOutput resetForReadingTimeRanges:localRanges];
  
  // read in the samples of the pass
  NSMutableArray *samples = [[NSMutableArray alloc] init];
  while((sample = [assetReaderOutput copyNextSampleBuffer])) {
    [samples addObject:(__bridge id)sample];
    CFRelease(sample);
  }
  
  // append samples to output using the recorded frame times
  for (NSInteger i=0; i= revSampleTimes.count) {
      NSLog(@"%s pass %ld: more samples than recorded frames! %d &gt;= %lu ", __FUNCTION__, (long)z, frameCount, (unsigned long)revSampleTimes.count);
      break;
    }
    
    // get the orig presentation time (from start to end)
    NSValue *eventValue = [revSampleTimes objectAtIndex:frameCount];
    CMTime eventTime = [eventValue CMTimeValue];
    
    // take the image/pixel buffer from tail end of the array
    CVPixelBufferRef imageBufferRef = CMSampleBufferGetImageBuffer((__bridge CMSampleBufferRef)samples[samples.count - i - 1]);
    
    // append frames to output
    BOOL append_ok = NO;
    int j = 0;
    while (!append_ok &amp;&amp; j &lt; fpsInt) {
      
      if (adaptor.assetWriterInput.readyForMoreMediaData) {
        append_ok = [adaptor appendPixelBuffer:imageBufferRef withPresentationTime:eventTime];
        if (!append_ok)
          NSLog(@&quot;%s Problem appending frame at time: %lld&quot;, __FUNCTION__, eventTime.value);
      }
      else {
        // adaptor not ready
        [NSThread sleepForTimeInterval:0.05];
      }
      
      j++;
    }
    
    if (!append_ok)
      NSLog(@&quot;%s error appending frame %d; times %d&quot;, __FUNCTION__, frameCount, j);
    
    frameCount++;
  }
  
  // release the samples array for this pass
  samples = nil;
}
</pre>
<p>You can see this in action in the app&#8217;s video filters as exemplified by some of the posts on <a href="https://www.instagram.com/beatcam/"> BeatCam&#8217;s Instagram page</a></p>
<p>The class used for creating reverse video, along with a sample XCode project is <a href="https://github.com/chrissung/CSVideoReverse">available on Github</a>. I hope you find it useful.</p>
<p>&#8212;</p>
<p>One aside: if you do find that you need to include a reversed version of the audio, then you will need to extract the audio from the video, reverse the order of the audio samples (make sure you take mono vs stereo into account), and then export a new video using the newly created reversed video and audio tracks.</p>
<p>The export, in this case, is achieved by creating a new AVMutableComposition, defining the tracks, length, and other details, and then exporting to file using AVAssetExportSession. Consult <a href="https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/03_Editing.html">Apple&#8217;s documentation</a> for a full explanation of how this is achieved.</p>
<div><a href="https://chrissung.com/2017/03/11/reverse-video-in-ios/"><img alt="BeatCam AutoDance Example" src="https://videos.files.wordpress.com/4APaG0K5/revex1_scruberthumbnail_0.jpg" width="160" height="120" /></a></div>]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2017/03/11/reverse-video-in-ios/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content width="400" height="400">
			<media:player url="https://videopress.com/v/4APaG0K5" />

			<media:rating scheme="urn:mpaa">g</media:rating>

			<media:title type="plain">BeatCam AutoDance Example</media:title>

			<media:thumbnail url="https://videos.files.wordpress.com/4APaG0K5/revex1_scruberthumbnail_0.jpg" width="256" height="256" />
		</media:content>
	</item>
		<item>
		<title>NFL Football and Raisins</title>
		<link>https://chrissung.com/2012/09/24/nfl-football-and-raisins/</link>
					<comments>https://chrissung.com/2012/09/24/nfl-football-and-raisins/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Mon, 24 Sep 2012 15:31:43 +0000</pubDate>
				<category><![CDATA[Random Thoughts]]></category>
		<category><![CDATA[Sports]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=183</guid>

					<description><![CDATA[It&#8217;s no secret that at this time of year, my (un)healthy addiction to NFL football rears its ugly head. I&#8217;m a lifelong Giants fan, which means that by law, I have to root against all other NFC East teams, and later in the season, against any other NFC teams that might prevent said G-Men from [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>It&#8217;s no secret that at this time of year, my (un)healthy addiction to NFL football rears its ugly head. I&#8217;m a lifelong Giants fan, which means that by law, I have to root against all other NFC East teams, and later in the season, against any other NFC teams that might prevent said G-Men from landing a playoff spot.</p>
<p>My daughter Alana is 5, and is just starting to discover professional sports and the differences between them. So last week, I thought she might have an interest in a 4pm game between the Eagles and the Ravens. The dialogue went something like this:</p>
<p>Me: Alana, who do you want to win &#8211; the Eagles or the Ravens?<br />
Alana: The Eagles or who? The Raisins &#8230;?<br />
Me: No, the Ravens<br />
Alana: (thinking) &#8230; I want the Raisins to win<br />
Me: No, no, it&#8217;s the Ravens, not the Raisins<br />
Alana: (spots closeup of Haloti Ngota) Wow! Look at that giant Raisin!</p>
<p>I&#8217;m now hoping that the Ravens continue to be the Raisins for a few years to come, as it is now standard practice to find out who the Raisins are playing this week. Turns out it was the Patriots in a hard-fought contest last night, and now the Browns this coming Thurs.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2012/09/24/nfl-football-and-raisins/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:thumbnail url="https://chrissung.com/wp-content/uploads/2012/09/baltimore-ravens-logo.gif" />
		<media:content url="https://chrissung.com/wp-content/uploads/2012/09/baltimore-ravens-logo.gif" medium="image">
			<media:title type="html">Baltimore-Ravens-Logo</media:title>
		</media:content>

		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>
	</item>
		<item>
		<title>Knicks&#8217; 2011-12 schedule &#8211; Knicks Blog</title>
		<link>https://chrissung.com/2011/12/07/knicks-2011-12-schedule-knicks-blog/</link>
					<comments>https://chrissung.com/2011/12/07/knicks-2011-12-schedule-knicks-blog/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Wed, 07 Dec 2011 13:03:10 +0000</pubDate>
				<category><![CDATA[Predictions]]></category>
		<category><![CDATA[Sports]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=143</guid>

					<description><![CDATA[Says Ian Begley: &#8220;Knicks vs. Heat, April 15: LeBron James says he doesn&#8217;t want to play the &#8220;villain&#8221; role anymore, but he won&#8217;t be able to avoid it on this night. James will be making his third trip to the Garden since spurning the Knicks [and others] to form a big three with Dwyane Wade [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Says Ian Begley:</p>
<p>&#8220;Knicks vs. Heat, April 15: LeBron James says he doesn&#8217;t want to play the &#8220;villain&#8221; role anymore, but he won&#8217;t be able to avoid it on this night. James will be making his third trip to the Garden since spurning the Knicks [and others] to form a big three with Dwyane Wade and Chris Bosh. This matchup is Game No. 60 of the season, <strong>so it could have serious playoff implications</strong>.&#8221;</p>
<p>via <a href="http://espn.go.com/blog/new-york/knicks/post/_/id/7058/page/rapidreaction/rapid-reaction-knicks-2011-2012-schedule">Rapid Reaction: Knicks&#8217; 2011-12 schedule &#8211; Knicks Blog &#8211; ESPN New York</a>.</p>
<p>This will be a good one to revisit in April &#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2011/12/07/knicks-2011-12-schedule-knicks-blog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>
	</item>
		<item>
		<title>Eclipse and SFTP</title>
		<link>https://chrissung.com/2011/11/16/eclipse-and-sftp/</link>
					<comments>https://chrissung.com/2011/11/16/eclipse-and-sftp/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Wed, 16 Nov 2011 11:11:38 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[sftp]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=130</guid>

					<description><![CDATA[One of my students at ITP just asked about file sync between one&#8217;s local file system to a remote file system using Eclipse and SFTP, so I put together a quick how-to, which might be of interest. The actual text/steps may vary, depending upon your version of Eclipse, but all the basics are there. The [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>
One of my students at ITP just asked about file sync between one&#8217;s local file system to a remote file system using Eclipse and SFTP, so I put together a quick how-to, which might be of interest.  The actual text/steps may vary, depending upon your version of Eclipse, but all the basics are there.
</p>
<p>
The one caveat of this process is that I&#8217;ve only been successful in setup and sync with an <b>existing</b> remote directory, and then importing it locally, not the other way around, e.g. exporting local to remote (though I have not tried very hard in this area &#8212; for whatever reason, the target has always existed whenever I&#8217;ve set up sync).  So a remote target folder of some kind must already exist before you sync it to a local one, if you&#8217;re using these instructions.
</p>
<p>
To equate a local directory with a pre-existing remote one:
</p>
<ol>
<li>Help &gt; Software Updates</li>
<li>Choose Available Software Tab</li>
<li>Click Add Site…, and then put <a href="http://eclipse.jcraft.com/" rel="nofollow">http://eclipse.jcraft.com/</a> for the URL field.</li>
<li>Choose SFTP Plug-in, and then click Install &#8230;, and then restart after the install</li>
<li>Using Project Explorer view, make a new local project</li>
<li>Create a folder within that project that will map to a remote folder</li>
<li>Right click on the local folder in Project Explorer and choose Import</li>
<li>In the Select dialog, choose Other &gt; SFTP</li>
<li>Choose the local folder as the one to receive the import</li>
<li>Create a new SFTP site and give your host and login info</li>
<li>If successfully connected to remote site, you should get the remote directory tree</li>
<li>Choose the remote folder to import</li>
<li>The remote files should now be in the local folder</li>
</ol>
<p>
Now to keep sync between these two:
</p>
<ol>
<li>Go to Window &gt; Show View &gt; Other&#8230; &gt; Team &gt; Synchronize
<li>Click the first upper right icon in the Synchronize tab</li>
<li>Choose SFTP from the Synchronize dialog</li>
<li>The previously mapped folder should appear with all files selected</li>
<li>Click Finish</li>
<li>Eclipse will ask you if you want to use Team Synch perspective.  Personally I don&#8217;t use this.  I just keep the Synchronize view as part of my workbench</li>
</ol>
<p>
To test:
</p>
<ol>
<li>Make a change in a file within the local folder</li>
<li>It should then appear in the Synchronize view in Outgoing mode</li>
<li>Using the buttons at the top of the Synchronize tab, or the right-click menus on any of the items that have changed, you can upload or check the diff between the local and remote counterpart</li>
</ol>
<p>
So there you have it.  For projects that involve multiple people, I would recommend using a version control system like Subversion, but for quick one-person, one code-base jobs, this works nicely &#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2011/11/16/eclipse-and-sftp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:thumbnail url="https://chrissung.com/wp-content/uploads/2011/11/reflective_eclipse.png" />
		<media:content url="https://chrissung.com/wp-content/uploads/2011/11/reflective_eclipse.png" medium="image">
			<media:title type="html">Reflective_Eclipse</media:title>
		</media:content>

		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>
	</item>
		<item>
		<title>Gimme The Strat</title>
		<link>https://chrissung.com/2011/08/22/gimme-the-strat/</link>
					<comments>https://chrissung.com/2011/08/22/gimme-the-strat/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Mon, 22 Aug 2011 13:52:23 +0000</pubDate>
				<category><![CDATA[Giveaways]]></category>
		<category><![CDATA[Guitar]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=96</guid>

					<description><![CDATA[ActiveMusician.com is winding down their Classic Vibe Strat Giveaway this Friday. How does one enter? Glad you asked. Simply give a like to ActiveMusician&#8217;s Facebook page and you&#8217;re entered. Right now, this is at ~1500 likes, so that&#8217;s your chances. Not bad for a guitar with a street value of $350. Guitar will ship from [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg"><img data-attachment-id="97" data-permalink="https://chrissung.com/2011/08/22/gimme-the-strat/classic-vibe-strat-giveaway/" data-orig-file="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg" data-orig-size="250,250" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Squier Classic Vibe Strat" data-image-description="" data-image-caption="" data-medium-file="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg?w=250" data-large-file="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg?w=250" src="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg" alt="Squier Classic Vibe Strat" title="Squier Classic Vibe Strat" class="alignleft size-full wp-image-97" /></a></p>
<p>ActiveMusician.com is winding down their Classic Vibe Strat Giveaway this Friday.  How does one enter?  Glad you asked.</p>
<p>Simply give a like to <a href="http://www.facebook.com/amstore">ActiveMusician&#8217;s Facebook page</a> and you&#8217;re entered.  Right now, this is at ~1500 likes, so that&#8217;s your chances.  Not bad for a guitar with a street value of $350.</p>
<p>Guitar will ship from our warehouse in NJ same or next biz day &#8212; depending on how long it takes to hear back from the winner (my guess is that it won&#8217;t take long).</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2011/08/22/gimme-the-strat/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2011/08/classic-vibe-strat-giveaway.jpg" medium="image">
			<media:title type="html">Squier Classic Vibe Strat</media:title>
		</media:content>
	</item>
		<item>
		<title>Play Songs, Not Riffs</title>
		<link>https://chrissung.com/2011/08/15/guitarists-hate-playing-the-entire-song/</link>
					<comments>https://chrissung.com/2011/08/15/guitarists-hate-playing-the-entire-song/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Mon, 15 Aug 2011 22:21:48 +0000</pubDate>
				<category><![CDATA[Guitar]]></category>
		<category><![CDATA[Musicianship]]></category>
		<category><![CDATA[advice]]></category>
		<category><![CDATA[guitar]]></category>
		<category><![CDATA[music]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=1</guid>

					<description><![CDATA[When I first starting learning to play guitar, and after the initial absorption of chords, scales, strumming, and the like, the focus was on playing all the classic guitar riffs from the bands of the day. Throw in an electric guitar copy and a cheap practice amp from my folks one birthday and all you [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://chrissung.com/wp-content/uploads/2017/03/am-guitar-fast.jpg"><img src="https://chrissung.com/wp-content/uploads/2017/03/am-guitar-fast.jpg" alt="" title="Fast Fingers" class="alignleft size-full wp-image-28" /></a></p>
<p>When I first starting learning to play guitar, and after the initial absorption of chords, scales, strumming, and the like, the focus was on playing all the classic guitar riffs from the bands of the day.  Throw in an electric guitar copy and a cheap practice amp from my folks one birthday and all you could hear from my room was many out-of-tune distorted licks all day long.</p>
<p>Eventually, the guitar came into tune (better ears, plus a Boss tuner), the distortion a bit better, but the premise was the same.  Learn all the most complicated guitar music note-for-note, rhythm and lead parts both, until I could play along with the recordings with ease.</p>
<p>This was not a strategy that I alone cultivated &#8212; in my town, this was the standard.  Everyone wanted to be the local hotshot guitarist, and those in the mix were practicing many hours daily to make this happen.  It was like our local version of the Guitar Olympics.</p>
<p>There are a few situations in which these skills really shine, most notably onstage with a band, and with all your own gear.  However, more often than not, life is not like that.  It might be a friend whose spirits need to be picked up and there&#8217;s an acoustic guitar laying around.  Or at a house party and people want to hear you play a song alone with a roommate&#8217;s beater guitar.</p>
<p>Being able to shred every Metallica lick is a valuable skill, but in these situations, knowing, playing, and singing (I&#8217;ll get to this) is infinitely better.  No one wants to hear the Best Guitar Licks from Metallica &#8212; they want to hear a Metallica song.  A good musician should be able to play the music that they care about in any situation, any environment, with whatever tools are available.</p>
<p>This is where the song comes in.  It was written for a reason and is the part with which the listener ultimately connects.  When you can replicate as much of that as possible, using whatever means are available, the connection becomes that much stronger.</p>
<p>And because the listener&#8217;s bond with the song is so strong, more often than not, they&#8217;ll forgive your singing if it turns out to be poor, as long as it&#8217;s heartfelt.  If you can tune a guitar, then you know what &#8220;in tune&#8221; and &#8220;out of tune&#8221; sounds like, so you should be able to correct your vocal pitch to the point where you can at least carry the tune.  If you can&#8217;t, you just haven&#8217;t spent enough time doing it.  Practice it with as much gusto as your playing and you&#8217;ll see the difference.</p>
<p>Now, presumably if you&#8217;ve learned riffs for various songs, then you know how those songs go.  It&#8217;s just a matter of remembering the chords, the song structure, and the lyrics.  To aid in this, you can look up the chords and melody on tab sites like <a href="http://www.ultimate-guitar.com/">Ultimate Guitar</a>, or if you want the official stuff, check out any online seller of music songbooks.</p>
<p>For me personally, I never knew many complete songs until my daughter was born.  When she was one year old, my wife and I could barely get her to eat while sitting in her high chair.  However, we eventually found out that if I sang and played guitar while food was in front of her, she&#8217;d become absorbed in the music and start to eat without noticing.</p>
<p>Thus, playing for her during mealtime became standard practice and I needed to start learning songs in a hurry.  So I pulled out my Beatles Complete songbook and started memorizing a new tune daily until enough I had enough repertoire to last a few meals.</p>
<p>In the end, it isn&#8217;t about being a jukebox or a karaoke machine.  It&#8217;s simply tapping the love of music shared by yourself you and the listener via your performance.</p>
<p>And that&#8217;s a very powerful thing.  Can you think of a better reason to be learning &amp; playing music?</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2011/08/15/guitarists-hate-playing-the-entire-song/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2017/03/am-guitar-fast.jpg" medium="image">
			<media:title type="html">Fast Fingers</media:title>
		</media:content>
	</item>
		<item>
		<title>James Taylor Has Magic Fingers</title>
		<link>https://chrissung.com/2011/08/08/james-taylor-and-his-fingers/</link>
					<comments>https://chrissung.com/2011/08/08/james-taylor-and-his-fingers/#respond</comments>
		
		<dc:creator><![CDATA[chrissung]]></dc:creator>
		<pubDate>Tue, 09 Aug 2011 01:15:35 +0000</pubDate>
				<category><![CDATA[Guitar]]></category>
		<category><![CDATA[Musicianship]]></category>
		<category><![CDATA[guitar]]></category>
		<category><![CDATA[music]]></category>
		<guid isPermaLink="false">http://www.chrissung.com/?p=51</guid>

					<description><![CDATA[Even with an artist as innovative as James Taylor, I assumed that most aspects of his guitar style and technique would be relatively orthodox. This turned out to be anything but. Though there are many great musical devices that he employs throughout his wide ranging repertoire of folk-rock hits, I find the most fascinating to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg"><img data-attachment-id="53" data-permalink="https://chrissung.com/2011/08/08/james-taylor-and-his-fingers/james-taylor/" data-orig-file="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg" data-orig-size="180,180" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="James Taylor" data-image-description="" data-image-caption="" data-medium-file="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg?w=180" data-large-file="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg?w=180" src="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg" alt="James Taylor" title="James Taylor" class="alignleft size-full wp-image-53" /></a></p>
<p>Even with an artist as innovative as James Taylor, I assumed that most aspects of his guitar style and technique would be relatively orthodox.  This turned out to be anything but.</p>
<p>Though there are many great musical devices that he employs throughout his wide ranging repertoire of folk-rock hits, I find the most fascinating to be the way he approaches fingering chords.  Specifically, his method for fingering the standard A major and D major chords deserves special attention.</p>
<p>Anyone who&#8217;s spent time with the guitar has probably delved into the classic CAGED guitar chords.  These are your most commonly played major chords for C, A, G, E, and D using open strings.  E, A, and D are especially interesting because these three are all variants of the same fingering, just starting on a different root or string.</p>
<p>In any event, all theory aside (though I&#8217;ll come back to this), most guitarists would finger a D chord as shown at below left.  However, James fingers a D chord as shown below at right.</p>
<table cellspacing="0" cellpadding="0" border="0" style="font-size:11px;">
<tr>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/standard_guitar_chord_d_major.jpg" width="300"><br />
<br /> Standard D major guitar chord</td>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/james_taylor_guitar_chord_d_major.jpg" width="300"><br />
<br /> James Taylor&#8217;s D major guitar chord</td>
</tr>
</table>
<p>This is not a hard substitution to make, and in some ways, feels just as natural or even more natural than the commonly accepted fingering.</p>
<p>However, when you start to look at the A major chord (below left), James uses a similar approach &#8212; an approach that in my estimation requires magic fingers.  The standard fingering for an A major chord is shown as left, but James uses a fingering shown at below right that is the exact inverse.</p>
<table cellspacing="0" cellpadding="0" border="0" style="font-size:11px;">
<tr>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/standard_guitar_chord_a_major.jpg" width="300"><br />
<br /> Standard A major guitar chord</td>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/james_taylor_guitar_chord_a_major.jpg" width="300"><br />
<br /> James Taylor&#8217;s A major guitar chord</td>
</tr>
</table>
<p>I do not have the biggest hands, and I can barely get my fingers to fit on or below the 2nd fret using this configuration.  To make matters worse, James is 6&#8217;3&#8243; with much larger hands, so either he has the world&#8217;s tiniest fingertips (this could be part of the equation), or he has magic fingers that can move in and out of this type of fingering with ease.</p>
<p>Taking this issue one step further, James often capos up to the 3rd fret for songs like &#8220;Fire and Rain&#8221; and &#8220;Something In The Way She Moves&#8221;, so that his A chord is actually a C chord (for vocal purposes).  If you look at a guitar, you can see that as you go higher up the neck, the space between frets becomes narrower and narrower.  But he still employs the same fingering technique.</p>
<p>From a theory standpoint (unfortunately, I did say I&#8217;d come back to this), James&#8217; approach to fingering these chords makes sense because, you can easily move from major and minor variants of the same chord simply by moving your 1st finger one fret lower (see below).</p>
<table cellspacing="0" cellpadding="0" border="0" style="font-size:11px;">
<tr>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/james_taylor_guitar_chord_a_major.jpg" width="300"><br />
<br /> James Taylor&#8217;s A major guitar chord</td>
<td valign="top">
<img src="https://i0.wp.com/img.etonals.com/doc/small/james_taylor_guitar_chord_a_minor.jpg" width="300"><br />
<br /> James Taylor&#8217;s A minor guitar chord</td>
</tr>
</table>
<p>However, the main advantage of the conventional approach is that you can throw in suspensions with ease.  With James&#8217; approach, you need to be pretty nimble with your pinky to make it happen (a whole different topic for another time), but if you have magic fingers, of course, well, no problem.</p>
<p>The only other variable in this equation is that the guitars he uses are somehow of a larger scale.  Custom made by <a href="http://olsonguitars.com/the-james-taylor-signature-models/">James A. Olson Guitars</a>, no mention is made of anything in the design that would favor this technique.</p>
<p>Thus, I propose that James Taylor has magic fingers.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://chrissung.com/2011/08/08/james-taylor-and-his-fingers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/ee28dc1f61aeb234e034c78759d73fc87d545455e5b1a083bed34fffe650bcce?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrissung100</media:title>
		</media:content>

		<media:content url="https://chrissung.com/wp-content/uploads/2011/08/james-taylor.jpg" medium="image">
			<media:title type="html">James Taylor</media:title>
		</media:content>

		<media:content url="http://img.etonals.com/doc/small/standard_guitar_chord_d_major.jpg" medium="image" />

		<media:content url="http://img.etonals.com/doc/small/james_taylor_guitar_chord_d_major.jpg" medium="image" />

		<media:content url="http://img.etonals.com/doc/small/standard_guitar_chord_a_major.jpg" medium="image" />

		<media:content url="http://img.etonals.com/doc/small/james_taylor_guitar_chord_a_major.jpg" medium="image" />

		<media:content url="http://img.etonals.com/doc/small/james_taylor_guitar_chord_a_major.jpg" medium="image" />

		<media:content url="http://img.etonals.com/doc/small/james_taylor_guitar_chord_a_minor.jpg" medium="image" />
	</item>
	</channel>
</rss>
