Description of Matlab/Octave Design Software for Assisted Alignments

A browser-displayable version of the source code described below can be found at The Complete Matlab/Octave Source Code for Design of Assisted Alignments. You can also download a zipped Matlab/Octave ".m" file of this code.

Usage of Third-Party Matlab Code

The source code described here makes use of a freeware third-party function for Matlab called isodd(), written by Ulf Carlberg, for determining if an integer is odd or even. To enable the code provided here to run without error, you must download isodd() from Matlab Central and place it in the project folder or a folder that's on the Matlab path. Under Octave, the name of the folder containing isodd() can be passed as an argument to addpath() in the octaverc startup file.


The function used for calculating design parameters for assisted alignments is calc_vented_box_params_n(). It is the only function in the source file calc_vented_box_params_n.m that's callable from external scripts used in system design. It takes arguments qt, ql, n and class, corresponding to QT, QL, system order n and the alignment class respectively. When n < 6, there is no concept of alignment class, so when n = 5, the empty array [] is passed by the calling script as the class specification. When n is 6 or 7, a single integer suffices to specify the alignment class, in which case the calling script just passes a single integer for the class parameter. When n > 7, the alignment class is an array. If n were, say, 8, and the alignment class {1,4} per Table 5 were used, the array [1 4] would be passed as the class parameter.

calc_vented_box_params_n() first calls get_butterworth_pole_angles() to obtain θa, θb and the array of Butterworth pole angles θfi associated with the electrical filters. These three quantities are associated with the scalar program variables theta_a and theta_b, and the array variable theta_i respectively. The quantities QT, QL, n, θa, θb and θi are then passed to find_system_params(), which computes all necessary design parameters for both the enclosure and any electrical filters. These design parameters are packed into the data structure called params, which the calling script uses for the system design.


The job of get_butterworth_pole_angles() is to first compute all Butterworth pole angles for the given system order n (see (43) through (48)), then, based on the alignment class, determine which ones are assigned to the speaker plus box and which are assigned to the electrical filters. It begins by first doing some sanity checks. If any of these sanity checks fails, the Matlab function error() is called. The behavior of Matlab's error() function is such that any further execution is halted, and the error text is displayed to the user. There is no attempt to "muddle through" with bad data. After the sanity checks, ang_count is computed, which corresponds to m of (106). Then the number of elements in the class array is calculated and assigned to class_size. The value of class_size is 0 in the case of n = 5, as an empty class array must be passed in that case. When n is 6 or 7, class_size is 1, while for n greater than 7, class_size is greater than 1. Further sanity checks are done to make sure that class_size is exactly two less than ang_count.

For the case of n = 5, there is no consideration of alignment class, so θa and θb can immediately be assigned the values π / 5 and 2π / 5 respectively, while the θi array is left empty. For n > 5, the Butterworth pole angles are computed and assigned to the theta_all array variable. This is done by setting its first element to either π / n when n is odd, or π / 2n when n is even, then incrementing all subsequent angles by π / n from the previous one. Once the array is populated, it is sorted in descending order. As previously described, the alignment class is defined as an integer or collection of integers which form an index or indices into the theta_all array, whose angles must be sorted in descending order. The subset of the Butterworth pole angles in theta_all having said index or indices is assigned to the external electrical filter or filters.

The partitioning of the Butterworth pole angles is done in the following way. First, each index of the theta_all array is checked to see if it is found in the class array. If it is found, its corresponding angle in theta_all is assigned to the theta_i array, to be associated with the electrical filter. If the index is not found in the class array, the corresponding angle from theta_all is assigned to the theta_ab array, to be associated with the loudspeaker plus box. Given a correctly-specified class array, theta_ab must have exactly two valid elements, while theta_i must have m - 2 elements, where m is given by (106). Checking of this condition is facilitated by initializing theta_ab and theta_i as empty arrays, then using the Matlab feature of automatic array resizing if elements are assigned to array indices that are currently out of range. In this way, since elements are assigned sequentially to array indices which begin with 1 and increment by 1, the final size of each array is also the number of valid elements it contains. Checking the size of each array after the partitioning therefore constitutes a sanity check for a correctly-formed class array. Then, theta_a is set to the smaller value of theta_ab while theta_b is set to the larger. The data structure called angles, which is the return value of get_butterworth_pole_angles() has its theta_a, theta_b and theta_ab components assigned from the theta_a, theta_b and theta_ab local variables respectively. This angles structure is then returned to the caller, calc_vented_box_params_n().


After the Butterworth pole angles θa, θb and the set of θi are calculated by get_butterworth_pole_angles(), these angles, in addition to QT, QT and n, are passed to find_system_params() by calc_vented_box_params_n(). The task of find_system_params() is to calculate h and α for designing the box, as well as the calculation of the transfer functions of the external electrical filters. The algorithms of find_system_params() are for the most part identical to those of the find_system_params_cheby_butter() function used in the design software for the unassisted alignments. These algorithms have been previously described in detail, including the relationships between the algorithms within the code and the procedures and equations derived previously herein. Consequently, only the differences between find_system_params() and find_system_params_cheby_butter() will be described. Examination of (76) and (80) through (83) shows that once θa and θb are chosen, the computations of the coefficients of G(s), the loudspeaker portion of the system transfer function, are completely independent of n. That is, n only comes into play in the computation of θa and θb, allowing the design algorithms for the unassisted case of n = 4 and for arbitrary n to be substantively identical.

The algorithms of find_system_params() differ from those of find_system_params_cheby_butter() in the following ways:

  1. find_system_params() is used to compute the sub-Chebyshev alignments in addition to the Chebyshev and Butterworth alignments.
  2. find_system_params() checks if n is even or odd, and uses this information to choose the appropriate formula for the system -3dB frequency in the Chebyshev case.
  3. For the sub-Chebyshev case, find_f3_norm() must take into account the transfer functions of the electrical filters in computing the system -3dB frequency. It accomplishes this using H(s, a1, a2, a3, h, n, k, w1, theta_i) to calculate the overall system transfer function using (103).
  4. find_system_params() calls find_filter_params() to compute the transfer function coefficients of the external electrical filters.


This function finds the design parameters of the external electrical filters. The value of the lone ωp, the pole of the first-order filter, is computed only if n is odd. This is done by calc_fp_norm() using (104). The values of the collection ωfi are computed by calc_ff_norm() using (105). These frequencies are normalized to ωs by making use of the relationship implied by (14) that ω0 = ωs * sqrt(h). The collection Qfi of Q values for the second-order high-pass filters are computed using (101) by the function calc_qf().

Matlab/Octave Script for Sample Design of Assisted Vented-Box Alignment

A browser-displayable version of a script that exercises the source code described above can be found at Usage Example of Matlab/Octave Code for Assisted Alignments. You can also download a zipped Matlab/Octave ".m" file of this script.

This script is almost the same as the one previously described in connection with the design of unassisted alignments. The only substantive difference is that calc_vented_box_params_n() is called instead of calc_vented_box_params(). The former function for assisted alignments requires the user to specify the system order n and an alignment class. In this case, the system order is 8 and the alignment class is specified as [1 4]. The alignment class array corresponds to the class specification of {1, 4} in Table 5.