1873 | | /* Time for all ports to transmit whetever they have in their |
1874 | | * buffer. |
1875 | | */ |
1876 | | for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { |
1877 | | struct conf_port *conf_port = conf->ports[i]; |
1878 | | pjmedia_frame_type frm_type; |
1879 | | pj_status_t status; |
1880 | | |
1881 | | if (!conf_port) |
1882 | | continue; |
1883 | | |
1884 | | /* Var "ci" is to count how many ports have been visited. */ |
1885 | | ++ci; |
1886 | | |
1887 | | status = write_port( conf, conf_port, &frame->timestamp, |
1888 | | &frm_type); |
1889 | | if (status != PJ_SUCCESS) { |
1890 | | /* bennylp: why do we need this???? |
1891 | | One thing for sure, put_frame()/write_port() may return |
1892 | | non-successfull status on Win32 if there's temporary glitch |
1893 | | on network interface, so disabling the port here does not |
1894 | | sound like a good idea. |
1895 | | |
1896 | | PJ_LOG(4,(THIS_FILE, "Port %.*s put_frame() returned %d. " |
1897 | | "Port is now disabled", |
1898 | | (int)conf_port->name.slen, |
1899 | | conf_port->name.ptr, |
1900 | | status)); |
1901 | | conf_port->tx_setting = PJMEDIA_PORT_DISABLE; |
1902 | | */ |
1903 | | continue; |
1904 | | } |
1905 | | |
1906 | | /* Set the type of frame to be returned to sound playback |
1907 | | * device. |
1908 | | */ |
1909 | | if (i == 0) |
1910 | | speaker_frame_type = frm_type; |
1911 | | } |
1912 | | |
1913 | | /* Return sound playback frame. */ |
1914 | | if (conf->ports[0]->tx_level) { |
| 1874 | /* Get speaker frame */ |
| 1875 | status = write_port(conf, conf->ports[0], &frame->timestamp, |
| 1876 | &speaker_frame_type); |
| 1877 | if (status != PJ_SUCCESS || conf->ports[0]->tx_level == 0) { |
| 1878 | /* Force frame type NONE */ |
| 1879 | speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE; |
| 1880 | } else { |
| 1942 | /* Add mic signal to all listeners. */ |
| 1943 | for (i=0; i < conf->ports[0]->listener_cnt; ++i) { |
| 1944 | struct conf_port *listener; |
| 1945 | pj_int32_t *mix_buf; |
| 1946 | unsigned k; |
| 1947 | |
| 1948 | listener = conf->ports[conf->ports[0]->listener_slots[i]]; |
| 1949 | |
| 1950 | /* Skip if this listener doesn't want to receive audio */ |
| 1951 | if (listener->tx_setting != PJMEDIA_PORT_ENABLE) |
| 1952 | continue; |
| 1953 | |
| 1954 | mix_buf = listener->mix_buf; |
| 1955 | |
| 1956 | /* Mixing signals, |
| 1957 | * and calculate appropriate level adjustment if there is |
| 1958 | * any overflowed level in the mixed signal. |
| 1959 | */ |
| 1960 | for (k=0; k<conf->samples_per_frame; ++k) { |
| 1961 | mix_buf[k] += p_in[k]; |
| 1962 | /* Check if normalization adjustment needed. */ |
| 1963 | if (IS_OVERFLOW(mix_buf[k])) { |
| 1964 | /* NORMAL_LEVEL * MAX_LEVEL / mix_buf[k]; */ |
| 1965 | int tmp_adj = (MAX_LEVEL<<7) / mix_buf[k]; |
| 1966 | if (tmp_adj<0) tmp_adj = -tmp_adj; |
| 1967 | |
| 1968 | if (tmp_adj<listener->mix_adj) |
| 1969 | listener->mix_adj = tmp_adj; |
| 1970 | |
| 1971 | } |
| 1972 | } |
| 1973 | } |
| 1974 | |
| 1975 | /* Time for all ports to transmit whetever they have in their |
| 1976 | * buffer. |
| 1977 | */ |
| 1978 | for (i=1, ci=0; i<conf->max_ports && ci<conf->port_cnt-1; ++i) { |
| 1979 | struct conf_port *conf_port = conf->ports[i]; |
| 1980 | pjmedia_frame_type frm_type; |
| 1981 | pj_status_t status; |
| 1982 | |
| 1983 | /* Skip empty port. */ |
| 1984 | if (!conf_port) |
| 1985 | continue; |
| 1986 | |
| 1987 | status = write_port( conf, conf_port, &frame->timestamp, |
| 1988 | &frm_type); |
| 1989 | |
| 1990 | pj_bzero(conf_port->mix_buf, |
| 1991 | conf->samples_per_frame * sizeof(conf_port->mix_buf[0])); |
| 1992 | |
| 1993 | |
| 1994 | if (status != PJ_SUCCESS) { |
| 1995 | /* bennylp: why do we need this???? |
| 1996 | One thing for sure, put_frame()/write_port() may return |
| 1997 | non-successfull status on Win32 if there's temporary glitch |
| 1998 | on network interface, so disabling the port here does not |
| 1999 | sound like a good idea. |
| 2000 | |
| 2001 | PJ_LOG(4,(THIS_FILE, "Port %.*s put_frame() returned %d. " |
| 2002 | "Port is now disabled", |
| 2003 | (int)conf_port->name.slen, |
| 2004 | conf_port->name.ptr, |
| 2005 | status)); |
| 2006 | conf_port->tx_setting = PJMEDIA_PORT_DISABLE; |
| 2007 | */ |
| 2008 | continue; |
| 2009 | } |
| 2010 | } |
| 2011 | |