Compute the signed dB amplitude of the oscillating signal normalized wrt the number of bits used for the signal.
(signal, Fs, bits=16)
| 307 | |
| 308 | |
| 309 | def time_dB(signal, Fs, bits=16): |
| 310 | """ |
| 311 | Compute the signed dB amplitude of the oscillating signal |
| 312 | normalized wrt the number of bits used for the signal. |
| 313 | """ |
| 314 | |
| 315 | try: |
| 316 | import matplotlib.pyplot as plt |
| 317 | except ImportError: |
| 318 | import warnings |
| 319 | |
| 320 | warnings.warn("Matplotlib is required for plotting") |
| 321 | return |
| 322 | |
| 323 | # min dB (least significant bit in dB) |
| 324 | lsb = -20 * np.log10(2.0) * (bits - 1) |
| 325 | |
| 326 | # magnitude in dB (clipped) |
| 327 | pos = clip(signal, 2.0 ** (bits - 1) - 1, 1.0) / 2.0 ** (bits - 1) |
| 328 | neg = -clip(signal, -1.0, -(2.0 ** (bits - 1))) / 2.0 ** (bits - 1) |
| 329 | |
| 330 | mag_pos = np.zeros(signal.shape) |
| 331 | Ip = np.where(pos > 0) |
| 332 | mag_pos[Ip] = 20 * np.log10(pos[Ip]) + lsb + 1 |
| 333 | |
| 334 | mag_neg = np.zeros(signal.shape) |
| 335 | In = np.where(neg > 0) |
| 336 | mag_neg[In] = 20 * np.log10(neg[In]) + lsb + 1 |
| 337 | |
| 338 | plt.plot(np.arange(len(signal)) / float(Fs), mag_pos - mag_neg) |
| 339 | plt.xlabel("Time [s]") |
| 340 | plt.ylabel("Amplitude [dB]") |
| 341 | plt.axis("tight") |
| 342 | plt.ylim(lsb - 1, -lsb + 1) |
| 343 | |
| 344 | # draw ticks corresponding to decibels |
| 345 | div = 20 |
| 346 | n = int(-lsb / div) + 1 |
| 347 | yticks = np.zeros(2 * n) |
| 348 | yticks[:n] = lsb - 1 + np.arange(0, n * div, div) |
| 349 | yticks[n:] = -lsb + 1 - np.arange((n - 1) * div, -1, -div) |
| 350 | yticklabels = np.zeros(2 * n) |
| 351 | yticklabels = range(0, -n * div, -div) + range(-(n - 1) * div, 1, div) |
| 352 | plt.setp(plt.gca(), "yticks", yticks) |
| 353 | plt.setp(plt.gca(), "yticklabels", yticklabels) |
| 354 | |
| 355 | plt.setp(plt.getp(plt.gca(), "ygridlines"), "ls", "--") |
| 356 | |
| 357 | |
| 358 | def spectrum(signal, Fs, N): |