1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Prepare Core for av groupchats

This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-11-13 12:18:04 +01:00
parent 09790c95a4
commit 54462f0276
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
4 changed files with 106 additions and 12 deletions

View File

@ -45,6 +45,7 @@ const QString Core::CONFIG_FILE_NAME = "data";
const QString Core::TOX_EXT = ".tox";
QList<ToxFile> Core::fileSendQueue;
QList<ToxFile> Core::fileRecvQueue;
QHash<int, ToxGroupCall> Core::groupCalls;
Core::Core(Camera* cam, QThread *coreThread, QString loadPath) :
tox(nullptr), camera(cam), loadPath(loadPath), ready{false}
@ -95,12 +96,15 @@ Core::Core(Camera* cam, QThread *coreThread, QString loadPath) :
}
QString inDevDescr = Settings::getInstance().getInDev();
int stereoFlag = av_DefaultSettings.audio_channels==1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
if (inDevDescr.isEmpty())
alInDev = alcCaptureOpenDevice(nullptr,av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16,
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000);
alInDev = alcCaptureOpenDevice(nullptr,av_DefaultSettings.audio_sample_rate, stereoFlag,
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4)
/ 1000 * av_DefaultSettings.audio_channels);
else
alInDev = alcCaptureOpenDevice(inDevDescr.toStdString().c_str(),av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16,
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000);
alInDev = alcCaptureOpenDevice(inDevDescr.toStdString().c_str(),av_DefaultSettings.audio_sample_rate, stereoFlag,
(av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4)
/ 1000 * av_DefaultSettings.audio_channels);
if (!alInDev)
qWarning() << "Core: Cannot open input audio device";
}
@ -1632,11 +1636,17 @@ void Core::groupInviteFriend(int friendId, int groupId)
void Core::createGroup(uint8_t type)
{
if (type == TOX_GROUPCHAT_TYPE_TEXT)
{
emit emptyGroupCreated(tox_add_groupchat(tox));
}
else if (type == TOX_GROUPCHAT_TYPE_AV)
{
emit emptyGroupCreated(toxav_add_av_groupchat(tox, playGroupAudio, this));
}
else
{
qWarning() << "Core::createGroup: Unknown type "<<type;
}
}
bool Core::hasFriendWithAddress(const QString &addr) const

View File

@ -233,8 +233,11 @@ private:
static void onAvPeerTimeout(void* toxav, int32_t call_index, void* core);
static void onAvMediaChange(void *toxav, int32_t call_index, void* core);
static void joinGroupCall(int groupId, ToxAv *toxav); ///< Starts a call in an existing AV groupchat
static void leaveGroupCall(int groupId, ToxAv *toxav); ///< Will not leave the group, just stop the call
static void playGroupAudio(Tox* tox, int groupnumber, int friendgroupnumber, const int16_t* out_audio,
unsigned out_audio_samples, uint8_t decoder_channels, unsigned audio_sample_rate, void* userdata);
static void sendGroupCallAudio(int groupId, ToxAv* toxav);
static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled);
static void cleanupCall(int callId);
@ -268,6 +271,7 @@ private:
int dhtServerId;
static QList<ToxFile> fileSendQueue, fileRecvQueue;
static ToxCall calls[];
static QHash<int, ToxGroupCall> groupCalls; // Maps group IDs to ToxGroupCalls
QMutex fileSendMutex, messageSendMutex;
bool ready;

View File

@ -176,7 +176,6 @@ void Core::startCall(int friendId, bool video)
emit avCallFailed(friendId);
return;
}
}
}
@ -222,7 +221,7 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
return;
}
int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000;
int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000 * av_DefaultSettings.audio_channels;
uint8_t buf[framesize*2], dest[framesize*2];
bool frame = false;
@ -578,7 +577,7 @@ void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, un
if(state != AL_PLAYING)
{
alSourcePlay(alSource);
qDebug() << "Core: Starting audio source " << (int)alSource;
//qDebug() << "Core: Starting audio source " << (int)alSource;
}
}
@ -587,10 +586,81 @@ VideoSource *Core::getVideoSourceFromCall(int callNumber)
return &calls[callNumber].videoSource;
}
void Core::playGroupAudio(Tox* /*tox*/, int /*groupnumber*/, int /*friendgroupnumber*/, const int16_t* out_audio,
void Core::playGroupAudio(Tox* /*tox*/, int groupnumber, int /*friendgroupnumber*/, const int16_t* out_audio,
unsigned out_audio_samples, uint8_t decoder_channels, unsigned audio_sample_rate, void* /*userdata*/)
{
/// TODO: FIXME: Don't play groupchat audio on the main source!
/// We'll need some sort of call[] array but for groupchats, when that's done use this source
playAudioBuffer(alMainSource, out_audio, out_audio_samples, decoder_channels, audio_sample_rate);
if (!groupCalls[groupnumber].active)
return;
playAudioBuffer(groupCalls[groupnumber].alSource, out_audio, out_audio_samples, decoder_channels, audio_sample_rate);
}
void Core::joinGroupCall(int groupId, ToxAv *toxav)
{
qDebug() << QString("Core: Joining group call %1").arg(groupId);
groupCalls[groupId].groupId = groupId;
groupCalls[groupId].muteMic = false;
groupCalls[groupId].muteVol = false;
// the following three lines are also now redundant from startCall, but are
// necessary there for outbound and here for inbound
groupCalls[groupId].codecSettings = av_DefaultSettings;
groupCalls[groupId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH;
groupCalls[groupId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT;
// Audio
alGenSources(1, &calls[groupId].alSource);
alcCaptureStart(alInDev);
// Go
groupCalls[groupId].active = true;
groupCalls[groupId].sendAudioTimer->setInterval(5);
groupCalls[groupId].sendAudioTimer->setSingleShot(true);
connect(groupCalls[groupId].sendAudioTimer, &QTimer::timeout, [=](){sendGroupCallAudio(groupId,toxav);});
groupCalls[groupId].sendAudioTimer->start();
}
void Core::leaveGroupCall(int groupId, ToxAv *)
{
qDebug() << QString("Core: Leaving group call %1").arg(groupId);
groupCalls[groupId].active = false;
disconnect(groupCalls[groupId].sendAudioTimer,0,0,0);
groupCalls[groupId].sendAudioTimer->stop();
alcCaptureStop(alInDev);
}
void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
{
if (!groupCalls[groupId].active)
return;
if (groupCalls[groupId].muteMic)
{
groupCalls[groupId].sendAudioTimer->start();
return;
}
int framesize = (groupCalls[groupId].codecSettings.audio_frame_duration * groupCalls[groupId].codecSettings.audio_sample_rate) / 1000 * av_DefaultSettings.audio_channels;
uint8_t buf[framesize*2];
bool frame = false;
ALint samples;
alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
if(samples >= framesize)
{
alcCaptureSamples(alInDev, buf, framesize);
frame = 1;
}
if(frame)
{
int r;
if((r = toxav_group_send_audio(toxav_get_tox(toxav), groupId, (int16_t*)buf,
framesize, av_DefaultSettings.audio_channels, av_DefaultSettings.audio_sample_rate)) < 0)
{
qDebug() << "Core: toxav_group_send_audio error";
groupCalls[groupId].sendAudioTimer->start();
return;
}
}
groupCalls[groupId].sendAudioTimer->start();
}

View File

@ -16,7 +16,6 @@ class QTimer;
struct ToxCall
{
public:
ToxAvCSettings codecSettings;
QTimer *sendAudioTimer, *sendVideoTimer;
int callId;
@ -29,4 +28,15 @@ public:
NetVideoSource videoSource;
};
struct ToxGroupCall
{
ToxAvCSettings codecSettings;
QTimer *sendAudioTimer;
int groupId;
bool active;
bool muteMic;
bool muteVol;
ALuint alSource;
};
#endif // COREAV_H