• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

MM vs MI vs MC

Here are the measurements of my SAE 1000E. ~240 pF total, 2.1 grams.

When set to 1.8, my Fozgometer was only reading about 15 dB of separation. At 2.1, it's reading 25-30 dB.

SAE 1000E LCH_2.1g_MoFi StudioPhono_47k Ω_STR-100.png

SAE 1000E RCH_2.1g_MoFi StudioPhono_47k Ω_STR-100.png
 
Last edited:
Here are the measurements of my SAE 1000E. ~240 pF total, 2.1 grams.

When set to 1.8, my Fozgometer was only reading about 15 dB of separation. At 2.1, it's reading 25-30 dB.

View attachment 244334
View attachment 244335
Probably better centerng of armature in generator. Channel separation is a function of its symmetry, and affected by cartridge azimuth and tracking force.
 
Here are the measurements of my SAE 1000E. ~240 pF total, 2.1 grams.

When set to 1.8, my Fozgometer was only reading about 15 dB of separation. At 2.1, it's reading 25-30 dB.

View attachment 244334
View attachment 244335
I have a buddy coming over later with this cartridge. Apparently I missed the internet vinyl world's big event this month. I'll post my results so that we can compare.
 
Which pressing?
It looks like Issue 3 from 1973 on Discogs. Not sure if there are further pressing variations. I bought it a while back from 92hdcma on eBay. Bought 2 more copies recently but haven't opened them yet. I probably should, as this one may have wear from how many tests I've done.
 
SAE 1000E - Denon DP-30L II - 1.png

So far a good match except for distortion.

Then,
SAE 1000E - R - Denon DP-30L II - 1.png

Weird.

I then remembered noticing that the cartridge output pins were thinner than usual. By a decent amount, actually. So I tightened up the connection a bit and tried again.

SAE 1000E - Denon DP-30L II - 1.png

SAE 1000E - R - Denon DP-30L II - 1.png

Lowest point is actually -1.5dB as the 5kHz dip makes it look worse than it is.

This is all I managed to do as I wasn't going to troubleshoot further. I don't know if tightening the connection even more would alter the results. I wasn't going to crush my headshell wire terminals for a cartridge I don't own. Any number of things can be at play as these are old stock. Perhaps the cartridge isn't compatible with my tonearm. So inconclusive results. I say trust JP's.

@mackat: try tightening the connections to the cartridge pins. Also check for tarnish. I like to use Cape Cod polish on the pins of all cartridges I get. Also redo your Shure V15 V-MR measurement with the same thing in mind. There may be a pattern here. Double check all the headshell wires.

In the end, I am not getting great vibes from this cartridge. I don't know how I ever used turntables without these graphs. Even if it is an obsolete medium it still feels like I just left the stone age.
 
Last edited:
How was crosstalk?
I had taken out my Tacet test record to check but I got distracted with this nonsense and forgot about it. The beer also distracted me.
 
Upcoming measurements as time permits:

XL-33, XL-44, and XL-55 Pro.
XL-55 Pro MKII
XL-90 XL-50
MC-L1000
VST-V
Ultra 500
DL-303
DL-305

EDIT - add XL-88D
 
Last edited:
Upcoming measurements as time permits:

XL-33, XL-44, and XL-55 Pro.
XL-55 Pro MKII
XL-90 XL-50
MC-L1000
VST-V
Ultra 500
DL-303
DL-305

Have you already done your XL-88D? Or are you satistified that the plot that came with it is legit ;)
 
Have you already done your XL-88D? Or are you satistified that the plot that came with it is legit ;)

I did but can't find the source files any longer so will re-do it. The plot that came with it denotes it was done with a TRS-1005 record. Mine came close but not exact. No too surprising considering the age.
 
It would be nice with a thread devoted to cartridge measurements or perhaps one thread per cartridge or some subforum with them.
 
Ya I was thinking about that too. Minimally we should be adding descriptors and some key words to the posts here so this stuff can be found via search.
 
I picked up an EPC-205CMK3 with a functional stylus and suspension. The first one I bought had internal issues and the suspension was completely gone, unfortunately.

This one sounds quite good, but the channels diverge in different directions, so the suspension is likely at least somewhat deteriorated.

EPC-205CMK3 LCH 2_2_1.25g_MoFi StudioPhono_47k Ω ~240 pF_STR-100.png

EPC-205CMK3 RCH 2_2_1.25g_MoFi StudioPhono_47k Ω ~240 pF_STR-100.png



I also tried it with a Jico 205EX SAS/B, which is meant for the earlier iterations of 205C. I think it's safe to say it doesn't play well with the MK3. Kind of ironic, as it fits snugly in this one, while it's a bit loose in the one it's meant for. It measured far more normally in that one, though, when secured with Blu-Tack.


EPC-205CMK3 JICO LCH_2_1.25g_MoFi StudioPhono_47k Ω ~240 pF_STR-100.png

EPC-205CMK3 JICO RCH_2_1.25g_MoFi StudioPhono_47k Ω ~240 pF_STR-100.png
 
Hmm. Scale should’ve gone to 2dB/div on that last one. I’ll need to check that.

205CMK3 is a nice one. Expensive game finding good ones sadly.
 
Distortion looks off with the SAS? It needs taming of load.
 
Here's an updated script. Also includes some rude scaling logic and config to override and set a custom ylim. I haven't tested this version on Windows so there'll likely be a couple compatibility issues with the file attribute handling.

Code:
"""
PLEASE READ
To use this script you need to edit HOME to the directory where the .wav file is.
The .wav file can be any monotonic frequency sweep either up or down in frequency but
it must be trimmed at both ends to remove any leading silence. Frequencies below 1kHz are
ignored since virually all cartridges are well behaved below 1kHz.
Python does not read 24bit packed .wav's 16 bit is more than enough here.

The info_line should be alpha-numeric with entries separated by " / " only.  The script
will save a .png file that is named from the info line, replacing " / " with "_".  As
example "this / is / a / test" will create a file named "this_is_a_test.png"

plotstyle =

                1 - traditional
                2 - dual axis (twinx)
                3 - dual plot



VERSION 6BClean


"""

from scipy import signal
from scipy.io.wavfile import read
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import datetime
import os




#edit here to add a HOME directory, etc.

#HOME = '/Users/jjones/Documents/polar/' #THIS IS NOT NEEDED IF RAN FROM A FILE

_FILE = 'v15v-str100.wav'

infoline =  'V15VMR / 47k 350pF / STR-100'


roundlvl = 2
plotstyle = 2
plotdataout = 0


ovdylim = 0
ovdylimvalue = [-25,5]

#end Edit

print('Input File:   ' + str(_FILE))
print('Info Line:    ' + str(infoline))


def align_yaxis(ax1, ax2):
    y_lims = np.array([ax.get_ylim() for ax in [ax1, ax2]])

    # force 0 to appear on both axes, comment if don't need
    y_lims[:, 0] = y_lims[:, 0].clip(None, 0)
    y_lims[:, 1] = y_lims[:, 1].clip(0, None)

    # normalize both axes
    y_mags = (y_lims[:,1] - y_lims[:,0]).reshape(len(y_lims),1)
    y_lims_normalized = y_lims / y_mags

    # find combined range
    y_new_lims_normalized = np.array([np.min(y_lims_normalized), np.max(y_lims_normalized)])

    # denormalize combined range to get new axes
    new_lim1, new_lim2 = y_new_lims_normalized * y_mags
    ax1.set_ylim(new_lim1)
    ax2.set_ylim(new_lim2)



#Needed to steal Matlab's flat top window

def ft_window(n):
    w = []
    a0 = 0.21557895
    a1 = 0.41663158
    a2 = 0.277263158
    a3 = 0.083578947
    a4 = 0.006947368
    pi = np.pi

    for x in range(0,n):
        w.append(a0 - a1*np.cos(2*pi*x/(n-1)) + a2*np.cos(4*pi*x/(n-1)) - a3*np.cos(6*pi*x/(n-1)) + a4*np.cos(8*pi*x/(n-1)))
    return w

try:
    input = raw_input
except NameError:
    pass


y = read(_FILE)
Fs = int(y[0])
input_sig = y[1]


filelength = input_sig.shape[0] / Fs
print(f"Length:       {filelength}s")
print('Sample Rate:  ' + str("{:,}".format(Fs) + 'Hz'))




frequency = []
amplitude = []

frequency2h = []
amplitude2h = []

frequency3h = []
amplitude3h = []

freqout = []
ampout = []

freqout2h = []
ampout2h = []

freqout3h = []
ampout3h = []

F = int(Fs/100)
win = ft_window(F)

#For Fs sampling use small Fs/100 FFT's so frequency is f/100
#All common sampling rates are divisible by 100
#First try, no overlap and flat top window

#Find the minimum and maximum frequencies and flip the data if the sweep
#is going down in frequency.

y = abs(np.fft.rfft(input_sig[0:F]*win))
minf = np.argmax(y)

y = abs(np.fft.rfft(input_sig[len(input_sig)-F:len(input_sig)]*win))
maxf = np.argmax(y)

if maxf < minf:
    maxf,minf = minf,maxf
    input_sig = np.flipud(input_sig)



for x in range(0,len(input_sig)-F,F):
    y = abs(np.fft.rfft(input_sig[x:x+F]*win))
    f = np.argmax(y) #use largest bin
    if f >=10:
        frequency.append(f*100)
        amplitude.append(y[f])
    if 2*f<F/2-2 and f >= 10:
        f2 = np.argmax(y[(2*f)-2:(2*f)+2])
        frequency2h.append(f*100)
        amplitude2h.append(y[2*f-2+f2])
    if 3*f<F/2-2 and f >= 10:
        f3 = np.argmax(y[(3*f)-2:(3*f)+2])
        frequency3h.append(f*100)
        amplitude3h.append(y[3*f-2+f3])
 
amp = 0
count = 0
x = minf*100

for x in range(minf*100,(maxf+1)*100,100):
    for y in range(0,len(frequency)):
        if frequency[y] == x:
            amp = amp + amplitude[y]
            count = count + 1
    if count != 0:
        freqout.append(x)
        ampout.append(20*np.log10(amp/count))
    amp = 0
    count = 0

amp = 0
count = 0
x = minf*100

for x in range(minf*100,(maxf+1)*100,100):
    for y in range(0,len(frequency2h)):
        if frequency2h[y] == x:
            amp = amp + amplitude2h[y]
            count = count + 1
    if count != 0:
        freqout2h.append(x)
        ampout2h.append(20*np.log10(amp/count))
    amp = 0
    count = 0
 

amp = 0
count = 0
x = minf*100

for x in range(minf*100,(maxf+1)*100,100):
    for y in range(0,len(frequency3h)):
        if frequency3h[y] == x:
            amp = amp + amplitude3h[y]
            count = count + 1
    if count != 0:
        freqout3h.append(x)
        ampout3h.append(20*np.log10(amp/count))
    amp = 0
    count = 0


b, a = signal.iirfilter(3,.5, btype='lowpass') #filter some noise
ampout = signal.filtfilt(b,a,ampout)
ampout2h = signal.filtfilt(b,a,ampout2h)
ampout3h = signal.filtfilt(b,a,ampout3h)



norm = ampout[0]
ampout = ampout-norm #amplitude is in dB so normalize by subtraction at [0]
ampout2h = ampout2h-norm
ampout3h = ampout3h-norm


deltah = round((max(ampout)), roundlvl)
deltal = abs(round((min(ampout)), roundlvl))


print('Min Freq:     ' + str("{:,}".format(minf * 100) + 'Hz'))
print('Max Freq:     ' + str("{:,}".format(maxf * 100) + 'Hz'))

print('Min Ampl:     ' + str(round((min(ampout)), 4)) + 'dB')
print('Max Ampl:     ' + str(round((max(ampout)), 4)) + 'dB')
print('Delta:        ' + str(round((max(ampout) - min(ampout)), 4)) + 'dB')

print('Frequency:    ' + str(len(freqout)) + ' list elements')
print('Amplitude:    ' + str(len(ampout)) + ' list elements')
print('Amplitude 2h: ' + str(len(ampout2h)) + ' list elements')
print('Amplitude 3h: ' + str(len(ampout3h)) + ' list elements')


if plotdataout == 1:

    dampout = [*ampout, *[''] * (len(freqout) - len(ampout))]
    dampout2h = [*ampout2h, *[''] * (len(freqout) - len(ampout2h))]
    dampout3h = [*ampout3h, *[''] * (len(freqout) - len(ampout3h))]

    print('\nPlot Data: (freq, ampl, 2h, 3h)\n')

    dataout = list(zip(freqout, dampout, dampout2h, dampout3h))
    for fo, ao, ao2, ao3 in dataout:
        print(fo, ao, ao2, ao3, sep=', ')



plt.rcParams["xtick.minor.visible"] =  True
plt.rcParams["ytick.minor.visible"] =  True

if plotstyle == 1:
        fig, ax1 = plt.subplots(1, 1, figsize=(14,6))
 
        ax1.semilogx(freqout,ampout,color = 'b', label = 'Freq Response')
        ax1.semilogx(freqout2h,ampout2h,color = 'g', label = '2nd Harmonic')
        ax1.semilogx(freqout3h,ampout3h,color = 'r', label = '3rd Harmonic')

        ax1.set_ylabel("Amplitude (dB)")
        ax1.set_xlabel("Frequency (Hz)")

        ax1.legend(loc=4)
 

if plotstyle == 2:
        fig, ax1 = plt.subplots(1, 1, figsize=(14,6))
        ax2 = ax1.twinx()

        if max(ampout) <7:
            ax1.set_ylim(-25, 7)

        if max(ampout) < 4:
            ax1.set_ylim(-25,5)
  
        if max(ampout) < 2:
            ax1.set_ylim(-29,3)

        if max(ampout) < 0.5:
            ax1.set_ylim(-30,2)

        if ovdylim == 1:
            ax1.set_ylim(*ovdylimvalue)
 
        ax1.semilogx(freqout,ampout,color = 'b', label = 'Freq Response')
        ax2.semilogx(freqout2h,ampout2h,color = 'g', label = '2nd Harmonic')
        ax2.semilogx(freqout3h,ampout3h,color = 'r', label = '3rd Harmonic')

        align_yaxis(ax1, ax2)

        ax1.set_ylabel("Amplitude (dB)")
        ax2.set_ylabel("Distortion (dB)")
        ax1.set_xlabel("Frequency (Hz)")

        fig.legend(loc=4, bbox_to_anchor=(0.899, 0.11))
 

if plotstyle == 3:
        fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(14,6))

        ax2.grid(True, which="major", axis="both", ls="-", color="black")
        ax2.grid(True, which="minor", axis="both", ls="-", color="gainsboro")

        if max(ampout) <= 1.75 and min(ampout) >= -1.75:
                ax1.set_ylim(-2,2)

        ax1.semilogx(freqout,ampout,color = 'b', label = 'Freq Response')
        ax2.semilogx(freqout2h,ampout2h,color = 'g', label = '2nd Harmonic')
        ax2.semilogx(freqout3h,ampout3h,color = 'r', label = '3rd Harmonic')

        ax1.set_ylabel("Amplitude (dB)")
        ax2.set_ylabel("Distortion (dB)")
        ax2.set_xlabel("Frequency (Hz)")

        ax1.legend(loc=4)
        ax2.legend(loc=4)
 

ax1.grid(True, which="major", axis="both", ls="-", color="black")
ax1.grid(True, which="minor", axis="both", ls="-", color="gainsboro")



bbox_args = dict(boxstyle="round", color='b', fc='w', ec='b', alpha=1)
arrow_args = dict(arrowstyle="->")

ax1.annotate('+' + str(deltah) + ', ' + u"\u2212" + str(deltal) + ' dB', color='b', \
             xy=(1000,0), xycoords='data', \
             xytext=(-15, -20), textcoords='offset points', \
             ha="left", va="center", \
             bbox=bbox_args, \
             #arrowprops=arrow_args \
             )


 
ax1.set_xticks([1000,10000])
ax1.set_xticklabels(['1k','10k'])

ax1.set_title(infoline + "\n", fontsize=16)


mod_date = datetime.datetime.fromtimestamp(os.path.getmtime(_FILE))

plt.figtext(.17, .13, infoline + "\n" + _FILE + "\n" + \
            mod_date.strftime("%b %d, %Y %H:%M:%S"), fontsize=8)
  
plt.savefig(infoline.replace(' / ', '_') +'.png', bbox_inches='tight', pad_inches=.75, dpi=96)

plt.show()

print('\nDone!')
Trying to run your frequency response plotting script, I something wrong with my file directory, file location here?
1671787978259.png



Moved my Wav file to the directory where Python is installed and now I get this error?
1671788457491.png



The sweep file is 50 seconds
1671788556038.png


Cut off the last millisec part of the file with low signal and Voila!
1671788840540.png


'

'
1671789964907.png


No Ju just need to find out how to plot the whole frequency range and a script for the Wow&Flutter polar plot

Comparing plots by overlay
1671790299294.png
 

Attachments

  • 1671789638634.png
    1671789638634.png
    32 KB · Views: 64
Last edited:
Back
Top Bottom