From dd8c2caac72077ef4a440eab515780fbdea66c69 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Fri, 14 Nov 2014 20:13:08 -0500 Subject: [PATCH] more prep for audio groups --- src/audio_call.c | 20 ++++++++-------- src/audio_call.h | 4 +--- src/device.c | 4 ++-- src/device.h | 2 +- src/execute.c | 11 ++++++++- src/groupchat.c | 60 +++++++++++++++++++++++++++++++++++++++++++++--- src/groupchat.h | 5 ++++ src/help.c | 37 +++++++++++++++++++++++++++-- src/prompt.c | 9 ++++++-- src/prompt.h | 6 ----- src/toxic.h | 5 ++++ src/windows.c | 16 +++++++++++++ src/windows.h | 1 + 13 files changed, 150 insertions(+), 30 deletions(-) diff --git a/src/audio_call.c b/src/audio_call.c index 1e502d7..091b12b 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -180,10 +180,10 @@ void read_device_callback (const int16_t* captured, uint32_t size, void* data) } } - void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int size, void* userdata) { (void)userdata; + if (call_index >= 0 && ASettins.calls[call_index].ttas) { ToxAvCSettings csettings = ASettins.cs; toxav_get_peer_csettings(av, call_index, 0, &csettings); @@ -194,37 +194,37 @@ void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int siz int start_transmission(ToxWindow *self) { if ( !ASettins.av || self->call_idx == -1 ) return -1; - + /* Don't provide support for video */ if ( 0 != toxav_prepare_transmission(ASettins.av, self->call_idx, av_jbufdc * 2, av_VADd, 0) ) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Could not prepare transmission"); } - + if ( !toxav_capability_supported(ASettins.av, self->call_idx, AudioDecoding) || !toxav_capability_supported(ASettins.av, self->call_idx, AudioEncoding) ) return -1; - + if (set_call(&ASettins.calls[self->call_idx], true) == -1) return -1; - + ToxAvCSettings csettings; toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings); - + if ( open_primary_device(input, &ASettins.calls[self->call_idx].in_idx, csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!"); - + if ( register_device_callback(self->call_idx, ASettins.calls[self->call_idx].in_idx, read_device_callback, &self->call_idx, true) != de_None) /* Set VAD as true for all; TODO: Make it more dynamic */ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!"); - + if ( open_primary_device(output, &ASettins.calls[self->call_idx].out_idx, csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open output device!"); ASettins.calls[self->call_idx].has_output = 0; } - + return 0; } @@ -295,7 +295,7 @@ void callback_call_started ( void* av, int32_t call_index, void* arg ) ToxWindow* windows = arg; int i; for (i = 0; i < MAX_WINDOWS_NUM; ++i) - if (windows[i].onStart != NULL && windows[i].call_idx == call_index) { + if (windows[i].onStart != NULL && windows[i].call_idx == call_index) { windows[i].onStart(&windows[i], ASettins.av, call_index); if ( 0 != start_transmission(&windows[i]) ) {/* YEAH! */ line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); diff --git a/src/audio_call.h b/src/audio_call.h index d127a00..c5e0ed8 100644 --- a/src/audio_call.h +++ b/src/audio_call.h @@ -34,9 +34,7 @@ typedef enum _AudioError { ae_StartingCoreAudio = 1 << 2 } AudioError; -/* You will have to pass pointer to first member of 'windows' - * declared in windows.c otherwise undefined behaviour will - */ +/* You will have to pass pointer to first member of 'windows' declared in windows.c */ ToxAv *init_audio(ToxWindow *self, Tox *tox); void terminate_audio(); diff --git a/src/device.c b/src/device.c index f241627..3e27c90 100644 --- a/src/device.c +++ b/src/device.c @@ -351,7 +351,7 @@ DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, Dat return de_None; } -inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels) +inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t length, uint8_t channels) { if (device_idx >= MAX_DEVICES) return de_InvalidSelection; @@ -380,7 +380,7 @@ inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t leng } - alBufferData(bufid, device->sound_mode, data, lenght * 2 * channels, device->sample_rate); + alBufferData(bufid, device->sound_mode, data, length * 2 * channels, device->sample_rate); alSourceQueueBuffers(device->source, 1, &bufid); ALint state; diff --git a/src/device.h b/src/device.h index 29cacf7..50b5e43 100644 --- a/src/device.h +++ b/src/device.h @@ -81,7 +81,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx DeviceError close_device(DeviceType type, uint32_t device_idx); /* Write data to device */ -DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels); +DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t length, uint8_t channels); void print_devices(ToxWindow* self, DeviceType type); diff --git a/src/execute.c b/src/execute.c index aee25f0..0be70a3 100644 --- a/src/execute.c +++ b/src/execute.c @@ -74,7 +74,14 @@ static struct cmd_func chat_commands[] = { { "/answer", cmd_answer }, { "/reject", cmd_reject }, { "/hangup", cmd_hangup }, - { "/sdev", cmd_ccur_device }, + { "/mute", cmd_mute }, + { "/sense", cmd_sense }, +#endif /* AUDIO */ + { NULL, NULL }, +}; + +static struct cmd_func group_commands[] = { +#ifdef AUDIO { "/mute", cmd_mute }, { "/sense", cmd_sense }, #endif /* AUDIO */ @@ -165,6 +172,8 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode) break; case GROUPCHAT_COMMAND_MODE: + if (do_command(w, self, m, num_args, group_commands, args) == 0) + return; break; } diff --git a/src/groupchat.c b/src/groupchat.c index 8fd212e..99d102a 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -54,8 +54,41 @@ static int max_groupchat_index = 0; extern struct user_settings *user_settings; extern struct Winthread Winthread; -/* temporary until group chats have unique commands */ -extern const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE]; +#ifdef AUDIO +#define AC_NUM_GROUP_COMMANDS 21 +#else +#define AC_NUM_GROUP_COMMANDS 17 +#endif /* AUDIO */ + +/* Array of groupchat command names used for tab completion. */ +static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = { + { "/accept" }, + { "/add" }, + { "/avatar" }, + { "/clear" }, + { "/close" }, + { "/connect" }, + { "/decline" }, + { "/exit" }, + { "/group" }, + { "/help" }, + { "/log" }, + { "/myid" }, + { "/nick" }, + { "/note" }, + { "/quit" }, + { "/requests" }, + { "/status" }, + +#ifdef AUDIO + + { "/lsdev" }, + { "/sdev" }, + { "/mute" }, + { "/sense" }, + +#endif /* AUDIO */ +}; int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type) { @@ -497,7 +530,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) } else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) { diff = dir_match(self, m, ctx->line, L"/avatar"); } else { - diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE); + diff = complete_line(self, group_cmd_list, AC_NUM_GROUP_COMMANDS, MAX_CMDNAME_SIZE); } if (diff != -1) { @@ -645,6 +678,22 @@ static void groupchat_onInit(ToxWindow *self, Tox *m) wmove(self->window, y2 - CURS_Y_OFFSET, 0); } +#ifdef AUDIO + +void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm, + unsigned int samples, uint8_t channels, unsigned int sample_rate) +{ + // if (groupnum != self->num) + // return; + + // if (peernum < 0 || channels == 0 || channels > 2) + // return; + + // uint32_t length = samples * channels * sizeof(int16_t); +} + +#endif /* AUDIO */ + ToxWindow new_group_chat(Tox *m, int groupnum) { ToxWindow ret; @@ -660,6 +709,11 @@ ToxWindow new_group_chat(Tox *m, int groupnum) ret.onGroupNamelistChange = &groupchat_onGroupNamelistChange; ret.onGroupAction = &groupchat_onGroupAction; +#ifdef AUDIO + ret.onWriteDevice = &groupchat_onWriteDevice; + ret.device_selection[0] = ret.device_selection[1] = -1; +#endif + snprintf(ret.name, sizeof(ret.name), "Group %d", groupnum); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); diff --git a/src/groupchat.h b/src/groupchat.h index afa78c0..42f8c09 100644 --- a/src/groupchat.h +++ b/src/groupchat.h @@ -25,11 +25,16 @@ #include "toxic.h" #include "windows.h" +#include "audio_call.h" #define SIDEBAR_WIDTH 16 #define SDBAR_OFST 2 /* Offset for the peer number box at the top of the statusbar */ #define MAX_GROUPCHAT_NUM MAX_WINDOWS_NUM - 2 +#ifdef AUDIO +#define MAX_GROUP_PEERS 256 /* arbitrary limit, only used for audio */ +#endif + typedef struct { int chatwin; bool active; diff --git a/src/help.c b/src/help.c index bba09d2..88efe58 100644 --- a/src/help.c +++ b/src/help.c @@ -27,7 +27,7 @@ #include "help.h" #include "misc_tools.h" -#define HELP_MENU_HEIGHT 8 +#define HELP_MENU_HEIGHT 9 #define HELP_MENU_WIDTH 26 void help_init_menu(ToxWindow *self) @@ -86,6 +86,12 @@ static void help_draw_menu(ToxWindow *self) wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, "hat commands\n"); + wprintw(win, " g"); + wattron(win, A_BOLD | COLOR_PAIR(BLUE)); + wprintw(win, "r"); + wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); + wprintw(win, "oup commands\n"); + wattron(win, A_BOLD | COLOR_PAIR(BLUE)); wprintw(win, " f"); wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); @@ -194,7 +200,7 @@ static void help_draw_chat(ToxWindow *self) wprintw(win, " /hangup : Hangup active call\n"); wprintw(win, " /sdev : Change active device\n"); wprintw(win, " /mute : Mute active device if in call\n"); - wprintw(win, " /sense : VAD sensitivity treshold\n"); + wprintw(win, " /sense : VAD sensitivity threshold\n"); #endif /* AUDIO */ help_draw_bottom_menu(win); @@ -227,6 +233,25 @@ static void help_draw_keys(ToxWindow *self) wrefresh(win); } +static void help_draw_group(ToxWindow *self) +{ + WINDOW *win = self->help->win; + + wmove(win, 1, 1); + + wattron(win, A_BOLD | COLOR_PAIR(RED)); + wprintw(win, "Group audio commands:\n"); + wattroff(win, A_BOLD | COLOR_PAIR(RED)); + + wprintw(win, " /mute : Mute active device where type: in | out\n"); + wprintw(win, " /sense : VAD sensitivity threshold\n\n"); + + help_draw_bottom_menu(win); + + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); +} + static void help_draw_contacts(ToxWindow *self) { WINDOW *win = self->help->win; @@ -275,6 +300,13 @@ void help_onKey(ToxWindow *self, wint_t key) self->help->type = HELP_GLOBAL; break; +#ifdef AUDIO /* remove if/when we add non-audio group commands */ + case 'r': + help_init_window(self, 7, 80); + self->help->type = HELP_GROUP; + break; +#endif + case 'f': help_init_window(self, 10, 80); self->help->type = HELP_CONTACTS; @@ -318,6 +350,7 @@ void help_onDraw(ToxWindow *self) break; case HELP_GROUP: + help_draw_group(self); break; } } diff --git a/src/prompt.c b/src/prompt.c index 2314770..99c2a4a 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -48,13 +48,18 @@ extern struct Winthread Winthread; FriendRequests FrndRequests; +#ifdef AUDIO +#define AC_NUM_GLOB_COMMANDS 18 +#else +#define AC_NUM_GLOB_COMMANDS 16 +#endif /* AUDIO */ + /* Array of global command names used for tab completion. */ -const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = { +static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = { { "/accept" }, { "/add" }, { "/avatar" }, { "/clear" }, - { "/close" }, /* rm /close when groupchats gets its own list */ { "/connect" }, { "/decline" }, { "/exit" }, diff --git a/src/prompt.h b/src/prompt.h index 2d019c3..e184b8d 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -26,12 +26,6 @@ #include "toxic.h" #include "windows.h" -#ifdef AUDIO -#define AC_NUM_GLOB_COMMANDS 19 -#else -#define AC_NUM_GLOB_COMMANDS 17 -#endif /* AUDIO */ - #define MAX_FRIEND_REQUESTS 32 struct friend_request { diff --git a/src/toxic.h b/src/toxic.h index d515ebb..ee4bbe8 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -115,4 +115,9 @@ void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, const uint8_ void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata); void on_read_receipt(Tox *m, int32_t, uint32_t, void *userdata); +#ifdef AUDIO +void on_write_device(Tox *m, int groupnum, int peernum, const int16_t *pcm, unsigned int samples, + uint8_t channels, unsigned int sample_rate, void *userdata); +#endif /* AUDIO */ + #endif /* #define TOXIC_H */ diff --git a/src/windows.c b/src/windows.c index 7260022..e62a83a 100644 --- a/src/windows.c +++ b/src/windows.c @@ -253,6 +253,22 @@ void on_read_receipt(Tox *m, int32_t friendnumber, uint32_t receipt, void *userd windows[i].onReadReceipt(&windows[i], m, friendnumber, receipt); } } + +#ifdef AUDIO + +void on_write_device(Tox *m, int groupnum, int peernum, const int16_t *pcm, unsigned int samples, + uint8_t channels, unsigned int sample_rate, void *userdata) +{ + int i; + + for (i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i].onWriteDevice != NULL) + windows[i].onWriteDevice(&windows[i], m, groupnum, peernum, pcm, samples, channels, samples); + } +} + +#endif /* AUDIO */ + /* CALLBACKS END */ int add_window(Tox *m, ToxWindow w) diff --git a/src/windows.h b/src/windows.h index d622258..2e596e4 100644 --- a/src/windows.h +++ b/src/windows.h @@ -136,6 +136,7 @@ struct ToxWindow { void(*onEnd)(ToxWindow *, ToxAv *, int); void(*onRequestTimeout)(ToxWindow *, ToxAv *, int); void(*onPeerTimeout)(ToxWindow *, ToxAv *, int); + void(*onWriteDevice)(ToxWindow *, Tox *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int); int call_idx; /* If in a call will have this index set, otherwise it's -1. * Don't modify outside av callbacks. */