HA03: Lautsprecher-Analyse
1. Überblick
Diese Hausaufgabe vertifte die praktische Anwendung elektroakustischer Messtechniken am Beispiel einer kompletten Lautsprecher-Systemanalyse. Von der Rohmessung bis zur aktiven Frequenzweiche wurden alle Schritte der modernen Lautsprecherentwicklung behandelt.
2. Experimenteller Aufbau
2.1. Testsystem
- 2-Wege-Lautsprecher: Separater Tieftöner und Hochtöner
- Messtechnik: PyFar-basierte Impulsantwort-Messungen
- Messgeometrie: Nah- und Fernfeld-Konfigurationen
- Ziel: Optimaler linearer Frequenzgang durch aktive Entzerrung
2.2. Messsignale
# Exponential-Sweep für breitbandige Anregung
x = pf.signals.exponential_sweep_time(
n_samples=2**18,
frequency_range=[10, 22050],
sampling_rate=44100
)
3. Aufgabe 1: Grundmessungen und Systemidentifikation
3.1. Impulsantwort-Messung
Standard-Verfahren: Sweep-Dekonvolution für rauscharme Charakterisierung
# Aufnahme mit Referenz-Signal
recording = sd.playrec(x_padded.time.T, channels=2, blocking=True)
y = pf.Signal(recording[:,0].T, x_padded.sampling_rate) # Mikrofonsignal
x_reference = pf.Signal(recording[:,1].T, x_padded.sampling_rate) # Referenz
# Regularisierte Systemidentifikation
x_inverted = pf.dsp.regularized_spectrum_inversion(x_reference, (20, 21000))
h = y * x_inverted # Impulsantwort
Messaufbau-Varianten:
- Fernfeld: 3.5m Abstand für charakteristische Abstrahlung
- Nahfeld: Membran-/Port-Messungen für tieffrequente Charakterisierung
4. Aufgabe 2: Nahfeld-Pegelkorrektur
4.1. Keele-Methode für Bassreflex-Systeme
def add_nearfield(ir_m, ir_t, S_m, S_t):
# Flächenverhältnis-Korrektur für äquivalente Schallleistung
ratio = np.sqrt(S_t / S_m)
ir_t_corrected = pf.multiply((ir_t, ratio), domain='freq')
result = pf.add((ir_m, ir_t_corrected), domain='freq')
return result, ir_t_corrected
Physikalische Grundlage:
- Membranfläche:
S_membran = π * (0.261/2)²
- Port-Fläche:
S_tunnel = 0.233 * 0.035 * 4
(4 Ports) - Pegelkorrektur: Proportional zu √(Flächenverhältnis)
Anwendung: Kombination von Membran- und Port-Beiträgen für Gesamt-Tieftonverhalten
5. Aufgabe 3: Fernfeld-Fensterung
5.1. Reflexions-Eliminierung
def windowed_ir(ir, w_time):
start_samples = int(pf.dsp.find_impulse_response_start(ir, threshold=10))
w_size = int(round(w_time * ir.sampling_rate))
if w_size % 2 != 0:
w_size -= 1 # Gerade Anzahl für symmetrische Fenster
# Hann-Fenster um Impulsantwort-Onset
start = start_samples - w_size // 2
stop = start_samples + w_size // 2
ir_windowed = pf.dsp.time_window(
ir, [start, stop], window='hann', shape='symmetric',
unit='samples', crop='none', return_window=False
)
return ir_windowed
Parameter-Optimierung:
- Fensterlänge: 23 ms - Kompromiss zwischen Zeit- und Frequenzauflösung
- Zentrierung: Symmetrisch um Impulsantwort-Beginn
- Fenstertyp: Hann für optimale Leckage-Unterdrückung
5.2. Nah-/Fernfeld-Kombination
def combine_near_and_farfield(ir_near, ir_far, f_cut):
frequencies = ir_far.frequencies
f_index = np.argmin(np.abs(frequencies - f_cut))
# Amplituden- und Phasentrennung
abs_far = np.abs(ir_far.freq)
phase_far = np.angle(ir_far.freq)
abs_near = np.abs(ir_near.freq)
# Nahfeld-Skalierung bei Übergangsfrequenz
scale_factor = abs_far[..., f_index] / abs_near[..., f_index]
adjusted_abs_near = abs_near * scale_factor
# Nahtlose Spektral-Kombination
combined_abs = abs_far.copy()
combined_abs[..., :f_index] = adjusted_abs_near[..., :f_index]
# Rekonstruktion mit Fernfeld-Phase
combined_complex = combined_abs * np.exp(1j * phase_far)
return pf.Signal(combined_complex, ir_far.sampling_rate, domain='freq')
Übergangsfrequenz: 400 Hz - über Raumakustik-Einfluss, unter Chassis-Interferenzen
6. Aufgabe 4: Aktive Frequenzweiche und Entzerrung
6.1. Zeitausrichtung der Chassis
def shift_ir(ir_TT, ir_HT):
# Automatische Impuls-Erkennung
start_TT = pf.dsp.find_impulse_response_start(ir_TT, threshold=0)
start_HT = pf.dsp.find_impulse_response_start(ir_HT, threshold=0)
# Zeitliche Synchronisation
if start_HT < start_TT:
shift_samples = start_TT - start_HT
ir_HT = pf.dsp.time_shift(ir_HT, shift_samples, mode='linear')
elif start_TT < start_HT:
shift_samples = start_HT - start_TT
ir_TT = pf.dsp.time_shift(ir_TT, shift_samples, mode='linear')
return ir_TT, ir_HT
6.2. Linkwitz-Riley Crossover-Design
def crossover_LR_Filter(ir_TT, ir_HT, N, f_cross):
# 8. Ordnung für 48 dB/Oktave Flankensteilheit
TT_low = pf.dsp.filter.crossover(ir_TT, N, f_cross)
HT_high = pf.dsp.filter.crossover(ir_HT, N, f_cross)
# Kohärente Summierung
sum_signal = TT_low[0] + HT_high[1]
# Multi-Channel Output: [TT, HT, Summe]
time_data = np.stack((
TT_low[0].time[0],
HT_high[1].time[0],
sum_signal.time[0]
), axis=0)
time_data = time_data[:, np.newaxis, :] # Channel-Dimension
return pf.Signal(time_data, TT_low.sampling_rate, domain='time')
Filter-Parameter:
- Ordnung: N = 8 (48 dB/Oktave)
- Crossover-Frequenz: 1800 Hz (zwischen Chassis-Arbeitsbereichen)
- Typ: Linkwitz-Riley für ideale Amplituden-Summierung
6.3. Parametrische Entzerrung
# Beispiel Entzerrungsfilter-Kette
filtered_HT = pf.dsp.filter.bell(filtered_HT, 4000, -10, 0.5) # Resonanz-Dämpfung
filtered_TT = pf.dsp.filter.bell(filtered_TT, 280, 3, 4) # Bass-Korrektur
filtered_HT = pf.dsp.filter.bell(filtered_HT, 10000, 5, 0.3) # Brillanz-Anhebung
filtered_TT = pf.dsp.filter.low_shelf(filtered_TT, 120, 3, 1) # Tiefbass-Boost
filtered_HT = pf.dsp.filter.high_shelf(filtered_HT, 5500, 1, 1) # Luftigkeits-Tuning
Filter-Strategien:
- Bell-Filter: Schmalbandige Resonanz-Behandlung
- Shelf-Filter: Breitbandige tonale Balance
- Allpass-Filter: Phasenkorrektur ohne Amplituden-Änderung
7. Wichtige Konzepte
7.1. Lautsprecher-Physik
- Bassreflex-Abstimmung: Port und Membran als gekoppelte Resonatoren
- Chassis-Interferenz: Konstruktive/destruktive Überlagerung im Crossover-Bereich
- Zeitkohärenz: Phasenlinearität für natürliche Impulscharakteristik
7.2. Messtechnik
- Nah-/Fernfeld-Komplementarität: Vollständige Spektrum-Erfassung
- Fenster-Techniken: Raum-Einfluss-Eliminierung
- Regularisierte Dekonvolution: Robuste Systemidentifikation
7.3. Aktive Systeme
- Digitale Crossover: Präzise, veränderbare Frequenzaufteilung
- Parametrische EQ: Flexible Korrektur spezifischer Probleme
- Multi-Channel-DSP: Simultane Mehrkanal-Bearbeitung
8. Praktische Erkenntnisse
8.1. Messumgebung
- Raum-Akustik: Kritisch für Fernfeld-Messungen
- Mikrofonpositionierung: Reproduzierbarkeit essentiell
- Signal-Rausch-Verhältnis: Ausreichende Anregung für niedrige Pegel
8.2. Design-Optimierung
- Crossover-Wahl: Linkwitz-Riley für kohärente Summierung optimal
- Entzerrungs-Philosophie: Minimal-invasive Korrekturen bevorzugt
- Zeit-Alignment: Kritisch für natürliche Stereo-Abbildung
8.3. Software-Workflow
# Typischer Entwicklungs-Zyklus
def optimize_loudspeaker(measurements):
# 1. Rohdaten-Verarbeitung
ir_processed = apply_windowing(measurements['raw'])
# 2. Nah-/Fernfeld-Kombination
ir_combined = combine_measurements(ir_processed)
# 3. Zeitausrichtung
ir_aligned = align_drivers(ir_combined)
# 4. Entzerrung
ir_equalized = apply_correction_filters(ir_aligned)
# 5. Crossover-Integration
final_response = apply_crossover(ir_equalized)
return final_response
8.4. Qualitätskriterien
- Frequenzgang: ±3 dB Linearität über Nutzbereich
- Phasengang: Minimale Gruppenlaufzeit-Variation
- Impulsverhalten: Saubere, artefaktfreie Transientenantwort
9. Erweiterte Techniken
9.1. Automatisierte Optimierung
- Genetic Algorithms: Parameteroptimierung für komplexe Filter-Ketten
- Gradient Descent: Feintuning individueller Filter-Parameter
- Multi-Objective: Tradeoff zwischen verschiedenen Qualitäts-Metriken
9.2. Psychoakustische Optimierung
- Bark-Scale Weighting: Frequenzgruppenbasierte Bewertung
- Masking Models: Hörbarkeits-Schwellen für Korrektur-Prioritäten
- Loudness Modeling: Dynamik-abhängige Entzerrung
Diese Hausaufgabe demonstrierte den kompletten Workflow moderner Lautsprecher-Entwicklung von der Messung bis zur finalen Systemoptimierung.