106
107
m_MuteOnPowerOff(false),
107
108
m_VolumeZeroOnPowerOff(false),
108
109
m_restorePowerOn(false),
110
m_deviceProbeAtStartup(false),
109
111
m_V4L_version_override(V4L_Version2),
110
112
m_V4L_version_override_by_kernel_once(false),
111
113
m_RDS_notify(NULL),
222
224
s->register4_querySoundStreamRadioStation(this);
223
225
s->register4_queryEnumerateSourceSoundStreams(this);
227
s->register4_notifySoundStreamClosed(this);
225
228
s->register4_notifySoundStreamSourceRedirected(this);
226
229
s->register4_notifySoundStreamSinkRedirected(this);
227
230
notifySoundStreamCreated(m_SoundStreamSinkID);
337
340
sendMuteSink (m_SoundStreamSinkID);
338
341
sendUnmuteSink (m_SoundStreamSinkID);
340
notifyPowerChanged(true);
343
notifyPowerChanged(isPowerOn());
341
344
notifySoundStreamChanged(m_SoundStreamSourceID);
364
367
muteSource(m_SoundStreamSourceID, true);
367
sendStopPlayback(m_SoundStreamSinkID);
368
sendStopCapture(m_SoundStreamSinkID);
369
closeSoundStream(m_SoundStreamSourceID);
370
closeSoundStream(m_SoundStreamSinkID);
371
m_SoundStreamSourceID = createNewSoundStream(m_SoundStreamSourceID, false);
372
m_SoundStreamSinkID = m_SoundStreamSourceID;
370
sendStopRecording(m_SoundStreamSinkID);
371
sendStopPlayback (m_SoundStreamSinkID);
372
sendStopCapture (m_SoundStreamSinkID);
374
SoundStreamID oldSourceID = m_SoundStreamSourceID;
375
SoundStreamID oldSinkID = m_SoundStreamSinkID;
376
m_SoundStreamSourceID = createNewSoundStream(m_SoundStreamSourceID, false);
377
m_SoundStreamSinkID = m_SoundStreamSourceID;
378
closeSoundStream (oldSourceID);
379
closeSoundStream (oldSinkID);
373
381
notifySoundStreamCreated(m_SoundStreamSourceID);
374
382
notifyCurrentSoundStreamSinkIDChanged (m_SoundStreamSinkID);
375
383
notifyCurrentSoundStreamSourceIDChanged(m_SoundStreamSourceID);
964
m_caps = readV4LCaps(m_radioDev);
972
m_caps = (p || m_deviceProbeAtStartup) ? readV4LCaps(m_radioDev) : V4LCaps();
965
973
notifyRadioDeviceChanged(m_radioDev);
966
974
notifyDescriptionChanged(m_caps.description);
967
975
notifyCapabilitiesChanged(m_caps);
1036
1044
QString old_channel = m_CaptureMixerChannel;
1037
1045
m_CaptureMixerID = soundStreamClientID;
1038
1046
ISoundStreamClient *mixer = getSoundStreamClientWithID(m_CaptureMixerID);
1039
QStringList channels = mixer ? mixer->getPlaybackChannels() : QStringList();
1047
QStringList channels = mixer ? mixer->getCaptureChannels() : QStringList();
1041
1049
if (channels.size()) {
1042
1050
assignChannelIfValid(m_CaptureMixerChannel, channels[0], channels); // lowest priority
1044
1052
assignChannelIfValid(m_CaptureMixerChannel, "PCM", channels);
1045
1053
assignChannelIfValid(m_CaptureMixerChannel, "Wave", channels);
1054
assignChannelIfValid(m_CaptureMixerChannel, "Master", channels);
1046
1055
assignChannelIfValid(m_CaptureMixerChannel, "Line", channels);
1047
assignChannelIfValid(m_CaptureMixerChannel, "Master", channels);
1048
1056
assignChannelIfValid(m_CaptureMixerChannel, "Capture", channels);
1049
1057
assignChannelIfValid(m_CaptureMixerChannel, ch, channels); // highest priority
1159
bool V4LRadio::setDeviceProbeAtStartup(bool e)
1161
if (e != m_deviceProbeAtStartup) {
1162
m_deviceProbeAtStartup = e;
1163
notifyDeviceProbeAtStartupChanged(m_deviceProbeAtStartup);
1151
1168
bool V4LRadio::setMuteOnPowerOff(bool a)
1153
1170
if (a != m_MuteOnPowerOff) {
1171
1188
if (vo != m_V4L_version_override) {
1172
1189
m_V4L_version_override = vo;
1173
1190
notifyV4LVersionOverrideChanged(m_V4L_version_override);
1174
m_caps = readV4LCaps(m_radioDev);
1191
m_caps = (isPowerOn() || m_deviceProbeAtStartup) ? readV4LCaps(m_radioDev) : V4LCaps();
1175
1192
notifyCapabilitiesChanged(m_caps);
1176
1193
notifyDescriptionChanged(m_caps.description);
1220
1237
config.writeEntry("V4LVersionOverride", (int)m_V4L_version_override);
1221
1238
config.writeEntry("V4LVersionOverrideByKernelOnce", (int)m_V4L_version_override_by_kernel_once);
1239
config.writeEntry("DeviceProbeAtStartup", m_deviceProbeAtStartup);
1222
1240
saveRadioDeviceID(config);
1254
QString base_devname = "/dev/radio";
1256
QStringList testlist (base_devname );
1257
for (int i = 0; i < 9; ++i)
1258
testlist.append(base_devname + QString::number(i));
1260
QString found_devname;
1261
for (QList<QString>::const_iterator it = testlist.begin(); it != testlist.end(); ++it) {
1265
if (info.isReadable() && info.isWritable()) {
1266
found_devname = *it;
1271
QString found_devname = "";
1272
foreach (DeviceInfo devItem, getDeviceProposals()) {
1273
if (devItem.path.contains("radio") && devItem.info.exists()) {
1274
found_devname = devItem.path;
1275
if (devItem.info.isReadable() && devItem.info.isWritable()) {
1270
if (found_devname.isNull())
1271
found_devname = *it;
1272
logWarning(i18n("Device %1 does exist but is not readable/writable. Please check device permissions.", *it));
1279
logWarning(i18n("Device %1 does exist but is not readable/writable. Please check device permissions.", devItem.path));
1277
QString default_devname = found_devname.isNull() ? base_devname : found_devname;
1284
QString default_devname = "/dev/radio0";
1285
if (found_devname.isEmpty()) {
1286
logWarning(i18n("Could not find any radio device. Using the default path for now: %1", default_devname));
1288
default_devname = found_devname;
1279
QString devname = config.readEntry ("RadioDev", default_devname);
1291
QString devname = config.readEntry("RadioDev", default_devname);
1292
m_deviceProbeAtStartup = config.readEntry("DeviceProbeAtStartup", true);
1281
1294
if (found_devname.isNull() && devname == default_devname) {
1282
1295
logError(i18n("Could not find an accessible v4l(2) radio device."));
1323
1336
notifyActivePlaybackChanged(m_ActivePlayback, m_ActivePlaybackMuteCaptureChannelPlayback);
1324
1337
notifyMuteOnPowerOffChanged(m_MuteOnPowerOff);
1325
1338
notifyForceRDSEnabledChanged(m_RDSForceEnabled);
1339
notifyDeviceProbeAtStartupChanged(m_deviceProbeAtStartup);
1326
1340
notifyVolumeZeroOnPowerOffChanged(m_VolumeZeroOnPowerOff);
1327
1341
notifyV4LVersionOverrideChanged(m_V4L_version_override);
1344
1358
notifyPlaybackVolumeChanged(m_SoundStreamSinkID, m_defaultPlaybackVolume);
1363
QList<DeviceInfo> V4LRadio::getDeviceProposals(const QString &base) const
1365
QList<DeviceInfo> retval;
1367
QStringList filterList; filterList << "*radio*" << "*video*";
1368
QFileInfoList deviceInfos = devdir.entryInfoList(filterList, QDir::System, QDir::Name);
1369
QFileInfoList subdirs = devdir.entryInfoList(QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Executable | QDir::Readable, QDir::Name);
1371
foreach(const QFileInfo &deviceInfo, deviceInfos) {
1372
if (deviceInfo.exists()) {
1373
QString devName = deviceInfo.absoluteFilePath();
1374
bool permsOK = deviceInfo.isReadable() && deviceInfo.isWritable();
1375
V4LCaps caps = getCapabilities(devName);
1376
QString descr = caps.deviceDescription;
1377
descr = descr.isEmpty() ? devName : descr + "[" + devName + "]";
1379
descr = i18n("%1 (insufficient permissions)").arg(descr);
1381
retval.append(DeviceInfo(devName, deviceInfo, caps, descr));
1385
foreach(const QFileInfo &subdir, subdirs) {
1386
retval.append(getDeviceProposals(subdir.absoluteFilePath()));
1347
1394
void V4LRadio::startPlugin()
1349
1396
PluginBase::startPlugin();
1401
1448
notifyCapabilitiesChanged(m_caps);
1402
1449
notifyDescriptionChanged(m_caps.description);
1404
/* m_mixer_fd = open(m_mixerDev, O_RDONLY);
1405
if (m_mixer_fd < 0) {
1408
logError("V4LRadio::radio_init: " +
1409
i18n("Cannot open mixer device %1", m_mixerDev));
1413
1451
m_radio_fd = open(m_radioDev.toLocal8Bit(), O_RDONLY);
1414
1452
if (m_radio_fd < 0) {
1494
1530
l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN;
1495
1531
memcpy(buffer, caps.name, l);
1497
v4l_caps[V4L_Version1].description = i18n("V4L Plugin (V4L%1 mode): %2", V4L_Version1, buffer);
1533
v4l_caps[V4L_Version1].description = i18n("V4L Plugin (V4L%1 mode): %2", V4L_Version1, buffer);
1534
v4l_caps[V4L_Version1].deviceDescription = QString("%1").arg(buffer);
1499
1536
v4l_caps[V4L_Version1].hasMute = false;
1500
1537
v4l_caps[V4L_Version1].unsetVolume();
1537
1574
l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN;
1538
1575
memcpy(buffer, caps.name, l);
1540
v4l_caps[V4L_Version2].description = i18n("V4L Plugin (V4L%1 mode): %2", V4L_Version2, buffer);
1577
v4l_caps[V4L_Version2].description = i18n("V4L Plugin (V4L%1 mode): %2", V4L_Version2, buffer);
1578
v4l_caps[V4L_Version2].deviceDescription = QString("%1").arg(buffer);
1542
1580
v4l2_queryctrl ctrl;
1635
1673
logDebug("V4L final caps: " + c.getDebugDescription());
1637
// logDebug(c.hasMute ? i18n("Radio is mutable") : i18n("Radio is not mutable"));
1638
// logDebug(c.hasVolume ? i18n("Radio has Volume Control") : i18n("Radio has no Volume Control"));
1639
// logDebug(c.hasBass ? i18n("Radio has Bass Control") : i18n("Radio has no Bass Control"));
1640
// logDebug(c.hasTreble ? i18n("Radio has Treble Control") : i18n("Radio has no Treble Control"));
1820
r = ioctl(m_radio_fd, write ? VIDIOCSAUDIO : VIDIOCGAUDIO, m_audio);
1853
r = ioctl(m_radio_fd, (write ? VIDIOCSAUDIO : VIDIOCGAUDIO), m_audio);
1822
1855
m_stereo = (r == 0) && ((m_audio->mode & VIDEO_SOUND_STEREO) != 0);
2044
bool V4LRadio::noticeSoundStreamClosed(SoundStreamID id)
2046
if (m_SoundStreamSinkID == id || m_SoundStreamSourceID == id) {
2047
// FIXME: only power off if power off did not cause the sound stream close
2012
2056
bool V4LRadio::noticeSoundStreamSinkRedirected(SoundStreamID oldID, SoundStreamID newID)