5.23 学习总结

news2025/1/17 15:19:33

一.项目优化(语音通话)

实现步骤:

1.用户发送通话申请,并处理通话请求,如果同意,为两个用户之间进行连接。

2.获取到电脑的麦克风和扬声器,将获取到的语音信息转换成以字节数组的形式传递。

3.通过流循环的传递和接收字节数组,保持一个持续的语音通话。

4.另开一个线程当做计时器和结束聊天的作用。

实现代码:

1.获取电脑麦克风,将语音信息转换为字节数组,进行传递的方法(因为要保持通话,所以要循环的去发送字节数组,如果要中断聊天可以使用stop方法,来跳出循环;同时为了快速通畅的通讯,用1kb的数组去传递)

public void run() {

        try {
            captrueOutputStream=new BufferedOutputStream(s.getOutputStream());//建立输出流 此处可以加套压缩流用来压缩数据
        }
        catch (IOException ex) {
            return;
        }

        AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
        DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);

        try {
            line = (TargetDataLine) AudioSystem.getLine(info);
            line.open(format, line.getBufferSize());
        } catch (Exception ex) {
            return;
        }

        byte[] data = new byte[1024];//此处的1024可以情况进行调整,应跟下面的1024应保持一致
        int numBytesRead=0;
        line.start();

        while (thread != null) {
            numBytesRead = line.read(data, 0,1024);//取数据(1024)的大小直接关系到传输的速度,一般越小越快,
            try {
                captrueOutputStream.write(data, 0, numBytesRead);//写入网络流
            }
            catch (Exception ex) {
                break;
            }
        }

        line.stop();
        line.close();
        line = null;

        try {
            captrueOutputStream.flush();
            captrueOutputStream.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

2.获取电脑扬声器,接收传递来的字节数组,再转换为音频,通过扬声器播放。(接收与发送的类似,不过多赘述)

public void run() {

        AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
        BufferedInputStream playbackInputStream;

        try {
            playbackInputStream=new BufferedInputStream(new AudioInputStream(s.getInputStream(),format,2147483647));//封装成音频输出流,如果网络流是经过压缩的需在此加套解压流
        }
        catch (IOException ex) {
            return;
        }

        DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);

        try {
            line = (SourceDataLine) AudioSystem.getLine(info);
            line.open(format, bufSize);
        } catch (LineUnavailableException ex) {
            return;
        }

        byte[] data = new byte[1024];//此处数组的大小跟实时性关系不大,可根据情况进行调整
        int numBytesRead = 0;
        line.start();

        while (thread != null) {
            try{
                numBytesRead = playbackInputStream.read(data);
                line.write(data, 0,numBytesRead);
            } catch (IOException e) {
                break;
            }
        }

        if (thread != null) {
            line.drain();
        }

        line.stop();
        line.close();
        line = null;
    }

3.开启计时线程,监听语音聊天过程,添加结束聊天的按钮,中断循环。

private void openCallWindow1(Playback playback) {
        Stage callStage = new Stage();
        callStage.setTitle("通话中");

        BorderPane callRoot = new BorderPane();

        // 创建计时器标签
        Label timerLabel = new Label("00:00:00");
        timerLabel.setStyle("-fx-font-size: 24");
        callRoot.setCenter(timerLabel);

        // 创建关闭按钮
        Button closeButton = new Button("结束通话");
        closeButton.setOnAction(e -> {
            callStage.close();
            playback.stop();
        });
        callRoot.setBottom(closeButton);

        // 创建计时器线程
        Thread timerThread = new Thread(() -> {
            int hours = 0, minutes = 0, seconds = 0;
            while (true) {
                try {
                    // 更新计时器标签
                    String time = String.format("%02d:%02d:%02d", hours, minutes, seconds);
                    Platform.runLater(() -> timerLabel.setText(time));
                    Thread.sleep(1000); // 休眠一秒钟
                    seconds++;
                    if (seconds == 60) {
                        seconds = 0;
                        minutes++;
                    }
                    if (minutes == 60) {
                        minutes = 0;
                        hours++;
                    }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        });
        timerThread.setDaemon(true); // 设置为守护线程,以确保程序退出时结束计时器线程
        timerThread.start(); // 启动计时器线程

        Scene scene = new Scene(callRoot, 300, 200);
        callStage.setScene(scene);
        callStage.show();
    }

效果展示:

 

 

 

 

二.算法练题

Codeforces Round 946 (Div. 3) D. Ingenuity-2

 

解题思路:

本题是一到模拟题,按照题目的要求来进行模拟即可,首先从题意我们可以得出以下几点:

1.在竖直或者水平方向(即x或者y方向上)的累计,只能是偶数,如果是奇数即输出 NO。

2.当只要两步时,x和y不可能为0,或者x和y不一样。

3.我们可以通过对x和y的值计算来得出H和R的行动,并且如果要保持一致,每一次的行动都应该是以2为单位进行。

#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n, m, t;
int main()
{
	cin >> t;
	while (t--)
	{
		string s, ss;
		int x=0, y=0;
		cin >> n;
		cin >> s;
        //计算x和y值
		for (int i = 0; i < n; i++) {
			if (s[i] == 'N') y += 1;
			if (s[i] == 'S') y -= 1;
			if (s[i] == 'E') x += 1;
			if (s[i] == 'W') x -= 1;
		}
        //假设一开始都是R行动
		for (int i = 0; i < n; i++) {
			ss += 'R';
		}
		if (x % 2 != 0 || y % 2 != 0) {
			cout << "NO" << endl;
			continue;
		}
		else if (x == 0 && y == 0) {
			if (n == 2) {
				cout << "NO" << endl;
				continue;
			}
            //如果要保持不动,一定会出现相反方向的行动
			else {
				if (s[0] == 'N') {
					ss[0] = ss[s.find('S')] = 'H';
				}
				if (s[0] == 'S') {
					ss[0] = ss[s.find('N')] = 'H';
				}
				if (s[0] == 'W') {
					ss[0] = ss[s.find('E')] = 'H';
				}
				if (s[0] == 'E') {
					ss[0] = ss[s.find('W')] = 'H';
				}
			}
		}
		else
		{   //通过x和y值去模拟一种可能
			for (int i = 0; i < n; i++) {
				if (s[i] == 'N' && y>0)
					ss[i] = 'H', y -= 2;
				if (s[i] == 'S' && y<0)
					ss[i] = 'H', y += 2;
				if (s[i] == 'W' && x<0)
					ss[i] = 'H', x += 2;
				if (s[i] == 'E' && x>0)
					ss[i] = 'H', x -= 2;
			}
		}
		cout << ss << endl;
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1682637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宇宙“超级地球”系列,你知道几个?

在宇宙中&#xff0c;可能存在着类地行星&#xff0c;这样的行星可能同样也拥有适宜生命存在的条件。银河系大约有60亿颗类地行星。 开普勒442b 这是脱离太阳系以后&#xff0c;人类发现的第二颗离地球最近的类地行星。开普勒442b这颗类地行星位于天鹅座&#xff0c;离地球约有…

机器学习势系列教程(3):cp2k的安装

大家好&#xff0c;我是小马老师。 本文继续介绍机器学习势相关内容&#xff1a;cp2k的安装。 和abacus一样&#xff0c;cp2k也是一款开源的第一性原理模拟软件&#xff0c;模拟的数据也可作为机器学习势的训练数据集。 cp2k安装方法也很多&#xff0c;常见的有docker安装、…

数据可视化第十天(爬虫爬取某瓣星际穿越电影评论,并且用词云图找出关键词)

开头提醒 本次爬取的是用户评论&#xff0c;只供学习使用&#xff0c;不会进行数据的传播。希望大家合法利用爬虫。 获得数据 #总程序 import requests from fake_useragent import UserAgent import timefuUserAgent()headers{User-Agent:fu.random }page_listrange(0,10) …

AI绘画Stable diffusion小白入门:文生图精讲,超全干货一定要看!

大家好&#xff0c;我是设计师阿威 今天&#xff0c;我们将深入了解Stable diffusion的文生图功能&#xff0c;让你也能生成满意的图片&#xff01; 如上图&#xff0c;这是Stable diffusion的文生图界面&#xff0c;这个界面总体可以分为五个区域&#xff1a; 模型区&#xf…

NegativePrompt:利用心理学通过负面情绪刺激增强大型语言模型

【摘要】大型语言模型 (LLM) 已成为各种应用不可或缺的一部分&#xff0c;从传统的计算任务到高级人工智能 (AI) 应用。这种广泛的应用促使社会科学等各个学科对 LLM 进行了广泛的研究。值得注意的是&#xff0c;研究表明 LLM 具有情商&#xff0c;可以通过积极的情绪刺激进一步…

UNION的使用

UNION的使用 给出将多条查询语句组合成单个结果集&#xff0c;两个表对应的列数和数据类型必须相同 UNION操作符&#xff1a; 返回两个查询结果集的并集&#xff0c;并去除重复记录 UNION ALL操作符 返回两个查询的结果集的并集。不去掉两个结果集的重复部分&#xff0c;重…

为什么说change Buffer写缓冲区,仅适用于辅助索引页

change buffer: 写缓冲区&#xff0c;是针对于二级索引页的更新优化措施。 change Bufer作用:在进行DML操作的时候&#xff0c;如果请求的是辅助索引(非唯一索引)并且没有在缓冲池中&#xff0c;并不会立刻将磁盘页加载到缓冲池&#xff0c;而是在CB记录缓冲变 更&#xff0c…

JVM(7):虚拟机性能分析和故障解决工具之jstat工具

1 jstat(JVM Statistics Monitoring Tool)作用 监视虚拟机各种运行状态信息&#xff0c;可以显示本地或者是远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据 2 命令格式 jstat [options vmid [interval[count]]] 参数解释 第一个参数&#xff1a;options 代…

linux:信号深入理解

文章目录 1.信号的概念1.1基本概念1.2信号的处理基本概念1.3信号的发送与保存基本概念 2.信号的产生2.1信号产生的五种方式2.2信号遗留问题(core,temp等) 3.信号的保存3.1 信号阻塞3.2 信号特有类型 sigset_t3.3 信号集操作函数3.4 信号集操作函数的使用 4.信号的处理4.1 信号的…

CSS学习笔记之中级教程(三)

14、CSS 下拉菜单 14.1 示例1&#xff1a;普通弹窗 思路&#xff1a;弹窗内容先隐藏display: none;&#xff0c;:hover时候修改弹窗部分的 display: block; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><me…

IT学习笔记--Kafka

Kafka概述: 定义: Kafka是一个分布式的基于发布/订阅模式的消息队列&#xff0c;主要应用于大数据实时处理领域。 消息队列消息队列的两种模式: 点对点模式: 消息生产者生产消息发送到Queue中&#xff0c;然后消息消费者从Queue中取出并且消费消息。 消息被消费以后&#…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言&#xff1a; 本游戏使用C语言和easyx图形库编写&#xff0c;通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧&#xff0c;以及锻炼我们独立的项目开发能力&#xff0c; 在开始编写代码之前&#xff0c;我们需要先了解一下游戏的基本规则…

git拉取项目前需要操作哪些?

1.输入 $ ssh-keygen -t rsa -C "秘钥说明" 按enter键 2.出现 ssh/id_rsa&#xff1a;(输入也可以不输入也可以) 然后按enter键 3.出现empty for no passphrase&#xff1a;(输入也可以不输入也可以) 然后按enter键 4.出现same passphrase again: (输入也可以不输入也…

FreeRTOS_互斥量_学习笔记

互斥量 数值只有0或1 谁获得互斥量&#xff0c;就必须由谁释放同一个互斥量。 但其实在freeRTOS中&#xff0c;任务A获取的互斥锁&#xff0c;任务B也能释放。因此谁上锁谁开锁只是约定&#xff0c;在程序实现上不是强制的。 “可重入的函数"是指&#xff1a;多个任务同时…

Python筑基之旅-MySQL数据库(一)

目录 一、MySQL数据库 1、简介 2、优点 2-1、开源和免费 2-2、高性能 2-3、可扩展性 2-4、易用性 2-5、灵活性 2-6、安全性和稳定性 2-7、丰富的功能 2-8、结合其他工具和服务 2-9、良好的兼容性和移植性 3、缺点 3-1、对大数据的支持有限 3-2、缺乏全文…

OSPF路由聚合

原理概述 与RIP不同&#xff0c;OSPF不支持自动路由聚合&#xff0c;仅支持手动路由聚合。OSPF的路由聚合有两种机制&#xff1a;区域间路由聚合和外部路由聚合。区域间路由聚合必须配置在ABR路由器上&#xff0c;指的是ABR在把与自己直接相连区域&#xff08;Area&#xff09…

运营美区TikTok小店常见问题汇总,你中了几个?

大家好&#xff0c;我是IPdodo的小编&#xff0c;专注于分享出海网络解决方案&#xff0c;致力于为TikTok运营人提供解决视频0播放、直播间卡顿、不进人甚至封号等问题的跨境网络专线。目前已经帮助数千位用户成功开启跨境业务。 今天&#xff0c;将针对美区TikTok小店的常见问…

树莓派学习笔记——树莓派的三种GPIO编码方式

1、板载编码&#xff08;Board pin numbering&#xff09;: 板载编码是树莓派上的一种GPIO引脚编号方式&#xff0c;它指的是按照引脚在树莓派主板上的物理位置来编号。这种方式对于初学者来说可能比较直观&#xff0c;因为它允许你直接根据引脚在板上的位置来编程。 2、BCM编…

CasaOS系统玩客云安装内网穿透工具实现无公网IP远程访问

文章目录 前言1. CasaOS系统介绍2. 内网穿透安装3. 创建远程连接公网地址4. 创建固定公网地址远程访问 前言 2月底&#xff0c;玩客云APP正式停止运营&#xff0c;不再提供上传、云添加功能。3月初&#xff0c;有用户进行了测试&#xff0c;局域网内的各种服务还能继续使用&am…

“手撕”String类+练习题

一、什么是String类 简单讲&#xff1a;是一个类&#xff01;创建字符串和字符串方法的类。 用 圈起来的叫字符&#xff0c;比如&#xff1a;a,b....里面只能有一个char类型的字符。 用" "圈起来的叫字符串&#xff0c;比如&#xff1a;"abc"..里面可以连…