docs: public synchronized void start() throws SocketException {
          if (!isRunning()) {
              socket.set(new DatagramSocket(BEAT_PORT));
              deliverLifecycleAnnouncement(logger, true);
              final byte[] buffer = new byte[512];
              final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
              Thread receiver = new Thread(null, new Runnable() {
                  @Override
                  public void run() {
                      boolean received;
                      while (isRunning()) {
                          try {
                              socket.get().receive(packet);
                              received = !DeviceFinder.getInstance().isAddressIgnored(packet.getAddress());
                          } catch (IOException e) {
                              // Don't log a warning if the exception was due to the socket closing at shutdown.
                              if (isRunning()) {
                                  // We did not expect to have a problem; log a warning and shut down.
                                  logger.warn("Problem reading from DeviceAnnouncement socket, stopping", e);
                                  stop();
                              }
                              received = false;
                          }
                          try {
                              if (received) {
                                  final Util.PacketType kind = Util.validateHeader(packet,  BEAT_PORT);
                                  if (kind != null) {
                                      switch (kind) {
  
                                          case BEAT:
                                              if (isPacketLongEnough(packet, 96, "beat")) {
                                                  deliverBeat(new Beat(packet));
                                              }
                                              break;
  
                                          case CHANNELS_ON_AIR:
                                              if (isPacketLongEnough(packet, 0x2d, "channels on-air")) {
                                                  byte[] data = packet.getData();
                                                  Set<Integer> audibleChannels = new TreeSet<Integer>();
                                                  for (int channel = 1; channel <= 4; channel++) {
                                                      if (data[0x23 + channel] != 0) {
                                                          audibleChannels.add(channel);
                                                      }
                                                  }
                                                  audibleChannels = Collections.unmodifiableSet(audibleChannels);
                                                  deliverOnAirUpdate(audibleChannels);
                                              }
                                              break;
  
                                          case SYNC_CONTROL:
                                              if (isPacketLongEnough(packet, 0x2c, "sync control command")) {
                                                  deliverSyncCommand(packet.getData()[0x2b]);
                                              }
                                              break;
  
                                          case MASTER_HANDOFF_REQUEST:
                                              if (isPacketLongEnough(packet, 0x28, "tempo master handoff request")) {
                                                  deliverMasterYieldCommand(packet.getData()[0x21]);
                                              }
                                              break;
  
                                          case MASTER_HANDOFF_RESPONSE:
                                              if (isPacketLongEnough(packet, 0x2c, "tempo master handoff response")) {
                                                  byte[] data = packet.getData();
                                                  deliverMasterYieldResponse(data[0x21], data[0x2b] == 1);
                                              }
                                              break;
  
                                          case FADER_START_COMMAND:
                                              if (isPacketLongEnough(packet, 0x28, "fader start command")) {
                                                  byte[] data = packet.getData();
                                                  Set<Integer> playersToStart = new TreeSet<Integer>();
                                                  Set<Integer> playersToStop = new TreeSet<Integer>();
                                                  for (int channel = 1; channel <= 4; channel++) {
                                                      switch (data[0x23 + channel]) {
  
                                                          case 0:
                                                              playersToStart.add(channel);
                                                              break;
  
                                                          case 1:
                                                              playersToStop.add(channel);
                                                              break;
  
                                                          case 2:
                                                              // Leave this player alone
                                                              break;
  
                                                          default:
                                                              logger.warn("Ignoring unrecognized fader start command, " +
                                                                      data[0x23 + channel] + ", for channel " + channel);
                                                      }
                                                  }
                                                  playersToStart = Collections.unmodifiableSet(playersToStart);
                                                  playersToStop = Collections.unmodifiableSet(playersToStop);
                                                  deliverFaderStartCommand(playersToStart, playersToStop);
                                              }
                                              break;
  
                                          default:
                                              logger.warn("Ignoring packet received on beat port with unexpected type: " + kind);
                                      }
                                  }
                              }
                          } catch (Throwable t) {
                              logger.warn("Problem processing beat packet", t);
                          }
                      }
                  }
              }, "beat-link BeatFinder receiver");
              receiver.setDaemon(true);
              receiver.setPriority(Thread.MAX_PRIORITY);
              receiver.start();
          }
      }