Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

1 Neutral

About jonfields45

  • Rank
    Just Startin'

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Allentown, PA
  • Registered Products
  1. Taking jf45ir To The Next Level Once you've captured your guitar, mic and pickup, with a DAW, it is a small matter to experiment with equalization of the mic recording. You can then export the EQ'd mic and raw pickup into a new WAV file for input to the jf45ir script. Fishman explicitly refers to traditional (IIR in DSP terminology) EQ in their process and I suspect all IRs marketed for acoustic guitar have some form of EQ applied to make them sound bigger or remove artifacts of the IR generation process (bass frequency emphasis -- a real issue for amplified acoustic guitar). jf45ir has two features that seem to keep the large scale EQ from deviating from the mic recording (no bass boost). One is huge segments of input WAV file are processed at one time. The 3 second segments (128K sample) translate into greater resolution in frequency domain yielding frequency coefficients only 1/3 Hz apart (for a DVD 48K sample rate). Drop that segment size down to 8K samples and the frequency coefficients are now 6 Hz apart which is unimportant for the higher harmonics but a real loss of resolution at bass frequencies. Also my algorithm zero's out (in dB) the IR for frequencies where there was essentially no pickup output. Starting with a neutral IR not EQ'd to someone else's tastes is a great platform for cooking your own large scale EQ into the IR. One user reports using this technique to remove a wolf tone from the IR for one of his instruments. This was something he previously dealt with manually at a gig which is now a bullet proof just load the IR solution.
  2. I now know a bit more about a match EQ and a friend has attempted to use one in place of an IR calculated with my script (he also has authored an IR generator for acoustic guitar using an approach he has not shared with me but conceptually similar). Bottom line it did not work, but it has some significant utility. I can speculate that a typical match EQ is an IIR technique which has some advantages in simpler hardware (or DSP workload) for more basic EQs like a graphic EQ. But it is not competitive with the an FIR where the resolution in the frequency domain is nearly unlimited. I am using 2^17 long sample segments which even after dividing by 2 to compensate for positive and negative frequencies is still a staggering 2^16 coefficients or frequency bands. It is possible to fold a match EQ back into the IR itself and that brings me to its possible utility. While it is not the case for the approach I took, some IR techniques gain up the bass response significantly which is a problem for acoustic guitar amplification. A match EQ is a good way to post process that type of IR to get the overall large scale frequency response back in-line with the original mic recording.
  3. They would need to be perfectly correlated and what you are proposing, though I've not tried it, is not going to work. You might get a good result installing a Powerbridge or other piezo pickup on your electric and using an existing IR for an acoustic guitar that has a relatively stiff top. I've attached an IR taken of a Fishman Sonitone installed on a plywood topped guitar. Others have found it useful with Yamaha Silent guitars and other UST or piezo equipped solid body instruments. That particular guitar was very bright sounding so the IR is not going to bring out much bass that is not already in the pickup output. You will still need to use basic EQ. jf45irPWFS.wav
  4. You will find my "production" script for download and up-to-date instructions on this Free Acoustic Guitar IR website: http://acousticir.free.fr/spip.php?article136&var_mode=calcul
  5. Another forum inspired this thought: My IR algorithm is simply the math I've described in previous posts. Other than decent volume matching, no clipping, and reasonable SNR, I've made no other assumptions other than the standard IR/FIR linear, time invariant, and finite. Magnetic pickups trained in open position with the expectation that it will be only useful in open position might work fine. A Baggs Session intentionally distorts and won't work. Using an LR Baggs Anthem with its mic does not violate the assumptions for my code, but it still might work better with the UST alone. One thing to consider, I made no provisions in my code for portability to a stompbox. The IR is portable. The IR generator is not. Commercial products to date are focused on that stompbox as the platform for a complete solution. I am freely using all the arithmetic precision and memory a PC or Mac has to offer (double precision floating point, huge sample sizes). At several steps in my process the math has to have sufficient resolution to accurately express 131,072 unique sine and cosine values between 0 and 2*pi. No way that is going to end up on a stompbox fixed point bit DSP running out of some tiny amount of memory. I should hesitate so say "my process" as the code is, except for half a dozen lines looking for near zeros in the pickup FFT, essentially right out of a textbook. This kind of arithmetic overkill allows me to avoid a lot of problems that might need tough to debug complicated solutions. It generates a neutral IR that focuses on making the pickup sound like the mic without also needing low/high cut filters, complex decisions on what part of your sample to use for the IR, or EQ to remove bass boost.
  6. I got asked a question about deconvolers and "can't you just use the mic output" in an email and maybe my reply is useful: Frequency sweep is an alternative to impulse response measurement, but you need a place to input the sweep (or impulse) and a place to measure. For the problem of making a pickup sound like a mic, you are postulating that there is the real guitar with a FIR filter (IR) to the pickup output, and another IR to the Mic output. Since you've postulated that these two parallel systems are linear, time invariant, and finite, there ought to be a single FIR filter or IR that can go from the pickup directly to the mic (and skip the middleman). This problem requires correlated samples of the mic and pickup (as far as I know and the market does not seem to have a better idea). In this case the postulated real guitar is not the one you are holding :~)!
  7. Forgive me as I am not familiar with Tone Match EQ deconvolver (did I quote that right?). I was trying to get my HX Stomp to replace a ToneDexter and approached the problem with that form of tunnel vision. I now gig with one pedal on the floor. The script I wrote takes 2^17 long segments of the pickup and mic, converts them to the frequency domain, takes their ratio, and then transforms that back to the time domain. Looking at the frequency domain, and recognizing the math has redundant positive and negative frequencies, you still have 2^16 (65,536) different frequency complex (phase and amplitude) coefficients. At 48 kHz sampling, they range from DC to 24 kHz. An acoustic guitar is going to range from 82 Hz to ~ 10kHz. ((10,000-81)/24,000) * 65,536 = 27,085 That is an equalizer with 27,085 bands! Graphic EQ (IIR, infinite impulse response, EQ in a digital implementation) has no practical way to get that level of detailed EQ. Not because the IIR filter is not theoretically capable, but IIR programming techniques rely on a relatively short list of "discovered" solutions and an IIR can't be programmed directly directly like an FIR (Finite Impulse Response filter programmed with an IR). The length of the final IR determines how low in frequency the FIR filter (the convolution engine) can operate effectively and 2048 is plenty for guitar. My code also generates a 1024 length IR which to my ear is very close in performance to the longer IR. The script's truncation step can be modified to longer IRs. They would not be useful in an HX Stomp but you could experiment with them in a DAW IR plug-in such as Reaper's ReaVerb. I think you will find it does not add value, but the prominent product in this segment, Audio Sprockets ToneDexter, has a single IR "slot" which is 8K long for home recording. My guess is it also has other signal processing tweaks as they market their shaping (EQ) of the IR generated by pure deconvolution.
  8. Assuming you've got my script, jf45ir.m, in the same directory as Test2.wav, and you've changed the working directory in Octave to that directory, then you just type this in the Octave command window: jf45ir('Test2')
  9. Not exactly what I am trying to do with my script. I am expecting you to start with a correlated (simultaneous) recording of your guitar's pickup and a mic of about one minute in length. My script then indeed does what can be called a deconvolution, but what it attempts to do is find that FIR transfer function (IR) that will make your pickup sound like your mic. You could imagine it deconvolves back to the real guitar and then convolves to get the mic output. For those of you who are interested, here is my description of the script's function: My primary resource was the ToneDexter patent's "state-of-the-art" discussion and Steiglitz "A Digital Signal Processing Primer: With Applications to Digital Audio and Computer Music 1st Edition" I am using a 44.1 kHz sample rate for my WAV files. The extra frequency content supported by DVD 48 kHz is not needed and the frequency domain calculations get wasted on more frequency bands above the guitar’s range. Cheap IR loaders run at 44.1, in time a fixed 2048 samples is longer at 44.1, and better loaders (such as my HX Stomp) can resample 44.1 to 48 on download. My code generates the IR with the same sample rate as the input WAV file. First, I extract segments of the recorded pickup and mic. I tried 1, 2, 4, 8, and 10 segments of lengths 2^15, 2^16, 2^17, 2^18, 2^19. Too short a sample sounded not as good as longer, and after a certain point longer was not better. The math of Discrete Fourier Transforms has a nasty quantization noise problem that favors longer segments. I also found if I averaged IRs from too many segments the result was so neutral it did nothing (maybe a noise gain-up problem). I settled on 4 segments, 2^17 (~3 seconds) long. I skip 6 seconds into the source wav file and grab a segment. I check it for clipping and having a peak less than -15 dB down from clipping. The segment is rejected for clipping or low SNR. I then skip ahead ~6 seconds and grab the next segment and repeat the clip/SNR test. I do this up to 8 times to yield 4 good segments. For 2^17 samples the low SNR test never triggered. For shorter segments it was common. I was careful not to record anything with clipping. Those of you who are familiar with how clipping distortion creates sharp edges and generates harmonics would probably not be surprised that taking a segment out of a longer sample does something similar at the beginning and end of the sample. A window function takes your segment and slowly raises the volume from zero and back to zero. I am using a Blackman window which is not far off the original Hamming window. The math again prefers a longer segment for less windowing harmonic generation. Next all the segments get Discrete Fourier Transformed (FFT). The mic FFT is divided by the pickup FFT. The division results are averaged together and then an Inverse Discrete Fourier Transform (IFFT) generates the IR. I then truncate the IR to 2048 samples. Minimum phase is an option mentioned in the ToneDexter patent and I also calculated minimum phase versions. I confirmed with frequency plots that the code works correctly. I could not hear any difference and gave up on that approach. I am thinking without the bass boost of other IR approaches the minimum phase version is not that important. My one piece of unique intellectual property (as far as I know) was a “no near zero” criteria in the pickup FFT (dividing by zero is bad and the IR can’t create something from nothing). I search the pickup FFT for coefficients (frequency bands) where the magnitude is more than 65 dB down (I tried 60, 65, 75, 80 and 85) from the peak. Those coefficients get replaced with “1” in both the pickup and mic FFTs. This produces a better sounding result with a better behaved frequency plot. The ToneDexter patent refers to many trade secrets on how to choose which segments to average into the final IR and when to stop. This is my approach to that problem...pure math. I also sanity tested the number of near zeros to be consistent with the amount of frequency headroom with 44.1 kHz sampling relative to the ~9 kHz bandwidth of an acoustic guitar. At this point I am producing IRs from four 2^17 sample segments, no near zeros with a 65 dB down criteria, and no minimum phase transformation.
  10. If you've changed the Octave working directory to the one with both my script and your wave file, and If the file is Test2.wav, then you need to type (note the single quotes): jf45ir('Test2') in the command window of Octave I corrected the link to the script above and here it is again: https://drive.google.com/open?id=1PtZmcDGo5yXbwjmHJGkhCX3uRyJDuRP-
  11. The two AGF links (hopefully working this time) are: https://www.acousticguitarforum.com/forums/showthread.php?t=568631 https://www.acousticguitarforum.com/forums/showthread.php?t=571361 My Octave script will generate an IR similar to ToneDexter or Aura. But it needs a correlated (recorded at the same time) recording of your guitar's pickup and a microphone. If you are interested in downloading Octave, which is free, you can run my script yourself. If you are curious this is the script's source code (jf45ir.m). Given the problem being addressed it is very simple and does a decent job. It works best with a piezo pickup. You can copy the following code into a file called jf45ir.m. I have fixed all the links, including the script Google Drive link, to work correctly. function jf45ir(input) # jonfields45@gmail.com # input.wav is the sample to be processed, pickup left, mic right diary logfile; diary on; # IR generation: ss = (2^17); # ~3 second segment size for analysis nstep = 2; # segment step ~6 seconds nstart = 3; # index into .wav in segments, ~6 seconds nlast = 17; # up to 8 segments checked for suitable SNR & no clip count = 0; # initialize good segment count nzcount = 0; # initialize near zero count accirfftnnz = zeros(ss,1); # initialize no near zero IR accumulator window = (.42-.5*cos(2*pi*(0:ss-1)/(ss-1))+.08*cos(4*pi*(0:ss-1)/(ss-1)))'; for n = nstart:nstep:nlast # process segments start = (((n-1) * ss) + 1); finish = (n * ss); [s,fs] = audioread([input,'.wav'],[start, finish]); # load segment smax = max(max(s)); clip = (smax > 0.999); # check for clipping toolow = (smax < 0.178); # more than 15 dB down if (clip == 0 && toolow == 0 && count < 4) # per segment IR pickup = s(:,1) .* window; mic = s(:,2) .* window; pupfft = fft(pickup); micfft = fft(mic); pupfftnnz = pupfft; micfftnnz = micfft; nearzero = 10^(-65/20)*abs(max(pupfft)); # ~0 is -65dB from peak for m = 1:1:ss if (abs(pupfft(m)) < nearzero) # Check near 0 div nzcount = nzcount + 1; # Count near 0s (pos & neg freq) pupfftnnz(m) = 1; # erase near zero micfftnnz(m) = 1; # erase near zero end end irfftnnz = micfftnnz ./ pupfftnnz; # segment IR=FFT(mic)/FFT(PUP) accirfftnnz = accirfftnnz + irfftnnz; # accumulate segment IRs count = count + 1; # increment processed segment count end end if(count==0) ['Zero Segments Processed due to Clip/Min errors'] return; end irnnz = ifft(accirfftnnz/count); # calc average IR over processed segments ir2048nnz = irnnz(1:2048); # truncate to 2048 avgnzcount = nzcount / (count*2); # pos freq avg near zero count per seg ['Processed Segments = ',num2str(count)] ['Average Near Zero per Segment = ',num2str(avgnzcount)] filename = ['jf45ir',input,'.wav']; audiowrite(filename,ir2048nnz,fs); # write IR fftir2048nnz = fft(ir2048nnz); # FFT final IR for frequency plot y = 20*log(abs(fftir2048nnz(2:1024))); # print frequency plot x = fs*(1:1023)/2048; semilogx(x,y); xlim([20 15000]); xlabel('Hz'); filename = ['FFTjf45ir',input,'.jpg']; ylabel([filename,' dB']); print(filename,'-djpeg'); filename = ['jf45ir1024',input,'.wav']; audiowrite(filename,ir2048nnz(1:1024),fs); # write IR # 50/50 IR generation irrms=(sum(ir2048nnz.*ir2048nnz))^0.5; ir2048nnz5050=(ir2048nnz*0.5); ir2048nnz5050(1)=ir2048nnz5050(1)+(irrms/2); filename = ['jf45ir5050',input,'.wav']; audiowrite(filename,ir2048nnz5050,fs); # write IR close; diary off; jf45ir.m
  12. EDIT: You will find my "production" script for download and up-to-date instructions on this website: http://acousticir.free.fr/spip.php?article136&var_mode=calcul EDIT: Links fixed! Check out this AGF thread for Doug Young’s demo of my IR along with my too long technical description of how my IR is generated (not required reading!). You will need headphones to hear this level of detail. Doug has previously been published in Acoustic Guitar magazine. https://www.acousticguitarforum.com/forums/showthread.php?t=568631 Essentially my IR script replaces the Aura library or the Audio Sprockets ToneDexter training process with a custom IR you generate on your own. If you would like to use an HX Stomp, as I do, as your do-it-all acoustic guitar pedal, this script plugs the only missing capability in the HX's repertoire. Doug's evaluation was with a very high end Barbera pickup. The improvement of an IR is much more startling using a standard UST such as a Fishman Matrix, Fishman Sonitone, or Baggs Element. My guitar has a Schatten passive HFN soundboard transducer and these IRs even work nicely with that fairly natural sounding pickup. The Easy Way to Generate a Custom IR for Your Guitar: Email (jonfields45@gmail.com) me a Dropbox or Google Drive link to your recording. If your .WAV file is less than 25 MB it can be sent as an email attachment. If you Zip up your recordings you can include several in a less than 25 MB email attachment. Generating the IR takes only seconds in Matlab (longer in Octave). If you want, send a few recordings with different mic placements. I like 8” from the neck/body joint, but a more distant mic placement might make what is a better IR for your usage. .WAV file at least 60 seconds long Pickup left, Mic right, set your DAW for the two to be about equal in volume No clipping Try to keep your peaks within 15 dB of clipping (decent SNR) I like open position strumming followed by “E” bar chords going from F to C followed by a little fingerpicking. Play whatever you think best exhibits your playing style and instrument. I’m not sure it really matters. Doug Young’s recording was a fingerstyle tune with occasional strums. I won’t be listening to your recording so don’t worry about impressive playing :~). I will send you back three IRs for each recording. They will be at the same sample rate as the recording you sent me. The one labeled 5050 will be 50% bypass mixed with 50% IR. The IRs will be 2048 samples except for the one explicitly labeled 1024. The three most common errors users have encountered are: To forget to pan the pickup left and mic right when exporting the sample from their DAW. The sample WAV file is less than 60 seconds. If running the script themselves (see next section) they forget to enclose the name of the wave file in single quotes, or include the extension instead of just the wave file name. The Do It Yourself Way: Download the free GNU math development environment Octave and follow the installation instructions for your PC (they support Linux, Windows 64, Widows 32, and Berkeley Unix). https://www.gnu.org/software/octave/download.html Download the Octave version of my IR generator (also attached to this post and downloadable if you log-in to this website): https://drive.google.com/open?id=1PtZmcDGo5yXbwjmHJGkhCX3uRyJDuRP- Place your guitar pickup/mic recordings in the same directory as my script jf45ir.m and double clip (run) jf45ir.m. The GUI version of Octave will open in that directory. Alternately, after installing Octave, run the GUI version and change the current directory to the one in which you placed my script and your recordings. If your recording is called mgit.wav, for example, then type the following in the Octave command window followed by a carriage return (don’t forget to include the single quotes before and after the file name and don’t include the ".wav" extension) : jf45ir('mgit') Octave will then generate four files, three IRs plus a frequency plot of the 100% IR. jf45irmgit.wav jf45ir5050mgit.wav jf45ir1024.wav FFTjf45irmgit.jpg Let me know how you make out with the IR. To my mind it is a pretty brute force implementation right out of a textbook, but it seems to produce useful results. The 1024 sample IR should be adequate for most instruments, but the longer version gives the IR better control over the low-E fundamental. I have put this script into the public domain as I think it adds important capability to a multi effects setup for use with an acoustic guitar. Most acoustic guitar solutions are hardwired feature sets including the few that implement IRs. Thanks, Jon jf45ir.m
  • Create New...