JUCE学习笔记05-音频输出基础(白噪)
JUCE学习笔记05——音频输出基础(白噪)
知识点:
1、AudioAppComponent类基础
2、音频应用程序的生命周期
目标:
了解AudioAppComponent类的三个方法与生命周期、生成白噪音、使用Slider控制音量
内容:
一、理解音频应用程序的生命周期
1、启动应用程序时AudioAppComponent的构造函数中设置输入输出通道数,触发音频处理的启动,并会调用prepareToPlay()方法,这里通过获取系统默认采样率和缓存区块大小信息实现该方法,并用组件的paint()方法显示在窗口上。
MainComponent::MainComponent()
{setSize (800, 600);if (RuntimePermissions::isRequired (RuntimePermissions::recordAudio)&& ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)){RuntimePermissions::request (RuntimePermissions::recordAudio,[&] (bool granted) { if (granted) setAudioChannels (2, 2); });}else{setAudioChannels (0, 2);//注册输入输出通道}
}
private:String msg; //调用信息String blockSize; //缓存区块大小String sysSampleRate; //默认系统采样率
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{msg = "Call: prepareToPlay()";blockSize << samplesPerBlockExpected;sysSampleRate << sampleRate;
}
void MainComponent::paint (Graphics& g)
{g.setFont(30); //字体大小g.setColour(Colours::red); //字体颜色g.drawText(msg, 10,10,300,30,Justification::left,false); //绘制文本g.drawText("Buffer: "+ blockSize, 10, 40, 300, 30, Justification::left, false);g.drawText("SampleRate: "+ sysSampleRate, 10, 70, 300, 30, Justification::left, false);
}
运行效果:
2、关闭应用程序时构造函数中的shutdownAudio()会调用releaseResources()方法释放音频源的缓存、关闭音频处理。
MainComponent::~MainComponent()
{//释放缓存、关闭音频设备shutdownAudio();
}
3、音频应用程序运行中依据音频系统的请求回调getNextAudioBlock ()方法获取播放所需的音频数据
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{
//生成播放音频数据的代码
}
二、实现getNextAudioBlock方法生成白噪音
1、白噪音(百度):白噪声是指在较宽的频率范围内,各等带宽的频带所含的噪声能量
相等的噪声。是一种功率谱密度为常数的随机信号。
简单理解:白噪音是通过在音频流中填充随机数所产生的音频信号
2、生成白噪音的方法
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{bufferToFill.clearActiveBufferRegion(); //JUCE自动生成的清理缓存方法,用于避免启动音频处理时爆音Random random; //随机数对象for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)//遍历需填充音频采样数据的通道{float* buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);//缓存块的起始点for (int sampleIndex = 0; sampleIndex < bufferToFill.numSamples; ++sampleIndex) //遍历采样点{buffer[sampleIndex] = (random.nextFloat()*2.0 - 1.0)*0.1; //写入随机采样值}}
}
三、使用Slider控制音量
1、主组件继承Slider::Listener
class MainComponent : public AudioAppComponent,public Slider::Listener
2、创建Slider、设置基本属性、添加至主组件、设置位置
MainComponent::MainComponent()
{addAndMakeVisible(volumeSlider); volumeSlider.setRange(0, 1, 0.01);//......其他代码
}
void MainComponent::resized()
{volumeSlider.setBounds(100, 100, 200, 200);
}
3、创建标签添加至Slider
MainComponent::MainComponent()
{volumeLabel.setText("Volume", NotificationType::dontSendNotification);volumeLabel.attachToComponent(&volumeSlider,true);//......其他代码
}
运行效果:
4、创建音量变量作为随机数的乘数
float volume;
5、实现Listener的sliderValueChanged(Slider * slider)方法,Slider的值与音量绑定
void MainComponent::sliderValueChanged(Slider * slider)
{if (slider == &volumeSlider)volume=volumeSlider.getValue();
}
6、添加Listener至Slider,初始化音量
MainComponent::MainComponent()
{volumeSlider.addListener(this); //Slider上添加监听volume = 0; //音量默认值
}
7、将音量乘数应用到音频数据流中
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{bufferToFill.clearActiveBufferRegion(); //JUCE自动生成的清理缓存方法,用于避免启动音频处理时爆音Random random;for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)//遍历需填充音频采样数据的通道{auto* buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);//缓存块的起始点for (int sampleIndex = 0; sampleIndex < bufferToFill.numSamples; ++sampleIndex) //遍历采样点{buffer[sampleIndex] = (random.nextFloat()*2.0 - 1.0)*volume;// 写入随机采样值}}
}
完整代码:
//MainComponent.h
#pragma once#include "../JuceLibraryCode/JuceHeader.h"//==============================================================================
/*This component lives inside our window, and this is where you should put allyour controls and content.
*/
class MainComponent : public AudioAppComponent,public Slider::Listener
{
public://==============================================================================MainComponent();~MainComponent();//=============AudioSource类方法================================================void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override;void releaseResources() override;//=============Component类方法==================================================void paint (Graphics& g) override;void resized() override;//=============Slider::Listener类方法===========================================void sliderValueChanged(Slider* slider) override;private:String msg; //调用信息String blockSize; //缓存区块大小String sysSampleRate; //默认系统采样率Slider volumeSlider; //音量Slider对象Label volumeLabel;float volume;JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
//MainComponent.cpp
#include "MainComponent.h"//==============================================================================
MainComponent::MainComponent()
{setSize (800, 600);addAndMakeVisible(volumeSlider);volumeSlider.setRange(0, 1, 0.01f);volumeLabel.setText("Volume", NotificationType::dontSendNotification);volumeLabel.attachToComponent(&volumeSlider,true);volumeSlider.addListener(this);volume = 0;// Some platforms require permissions to open input channels so request that hereif (RuntimePermissions::isRequired (RuntimePermissions::recordAudio)&& ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)){RuntimePermissions::request (RuntimePermissions::recordAudio,[&] (bool granted) { if (granted) setAudioChannels (2, 2); });}else{// 注册所需的输入和输出数,然后触发音频处理并调用prepareToPlay()方法setAudioChannels (0, 2);}
}MainComponent::~MainComponent()
{//释放缓存、关闭音频设备shutdownAudio();
}//==============================================================================
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{msg = "Call: prepareToPlay()";blockSize << samplesPerBlockExpected;sysSampleRate << sampleRate;
}void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
{bufferToFill.clearActiveBufferRegion(); //JUCE自动生成的清理缓存方法,用于避免启动音频处理时爆音Random random;for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)//遍历需填充音频采样数据的通道{auto* buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);//缓存块的起始点for (int sampleIndex = 0; sampleIndex < bufferToFill.numSamples; ++sampleIndex) //遍历采样点{buffer[sampleIndex] = (random.nextFloat()*2.0 - 1.0)*volume;// 写入随机采样值}}
}void MainComponent::releaseResources()
{}//==============================================================================
void MainComponent::paint (Graphics& g)
{g.setFont(30);g.setColour(Colours::red);g.drawText(msg, 10,10,300,30,Justification::left,false);g.drawText("BlockSize: "+ blockSize, 10, 40, 300, 30, Justification::left, false);g.drawText("SampleRate: "+ sysSampleRate, 10, 70, 300, 30, Justification::left, false);volumeSlider.setTextBoxStyle(Slider::TextBoxLeft,true,50,20);
}void MainComponent::resized()
{volumeSlider.setBounds(100, 100, 200, 200);
}void MainComponent::sliderValueChanged(Slider * slider)
{if (slider == &volumeSlider)volume=volumeSlider.getValue();}
JUCE学习笔记05-音频输出基础(白噪)相关推荐
- 学习笔记(05):Mysql数据库基础入门视频教程-自连接
立即学习:https://edu.csdn.net/course/play/9885/210119?utm_source=blogtoedu -- 子查询 -- 一个select语句包含另一个 ...
- 【Python学习笔记】第一章基础知识:格式化输出,转义字符,变量类型转换,算术运算符,运算符优先级和赋值运算符,逻辑运算符,世界杯案例题目,条件判断if语句,猜拳游戏与三目运算符
Python学习笔记之[第一章]基础知识 前言: 一.格式化输出 1.基本格式: 2.练习代码: 二.转义字符 1.基本格式: 2.练习代码: 3.输出结果: 三.输入 1.基本格式: 2.练习代码: ...
- ESP32 单片机学习笔记 - 05 - AP/Smart Config
ESP32 单片机学习笔记 - 05 - AP/Smart Config 终于把感觉必要的基础外设学完了,开始学esp32的主要特色功能--物联网~~?(大概) 一.WIFI热点 AP模式 编程指南: ...
- java学习笔记15--多线程编程基础2
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...
- Linux 学习笔记之超详细基础linux命令 Part 3
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 2----------------- ...
- JavaScript学习笔记05【高级——DOM对象】
w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...
- MySQL学习笔记05【多表操作、三大范式、数据库的备份和还原】
MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...
- 《Go语言圣经》学习笔记 第三章 基础数据类型
<Go语言圣经>学习笔记 第三章 基础数据类型 目录 整型 浮点数 复数 布尔型 字符串 常量 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记, ...
- MATLAB学习笔记2:MATLAB基础知识(下)
阅读前请注意: 1. 该学习笔记是华中师范大学HelloWorld程序设计协会2021年寒假MATLAB培训的学习记录,是基于培训课堂内容的总结归纳.拓展阅读.博客内容由 @K2SO4钾 撰写.编辑, ...
- Kotlin学习笔记(1)-- 基础语法
文章目录 Kotlin学习笔记(1)-- 基础语法 输出 语法 代码 输出 可读可改(var) 语法 代码 输出 内置数据类型 只读变量(val) 类型推断 编译时常量 语法 代码 输出 引用类型 r ...
最新文章
- 计算机中丢失sense3.dll,sense3.dll
- Spring-注入参数详解-[通过util命名空间简化集合类型的配置]
- c++ lambda基本语法
- 【学习笔记】opencv的python接口 几何变换
- avue中实现消息的实时展示
- bzoj4152: [AMPPZ2014]The Captain
- 那些年我们追过的计算机经典书
- python工作者工作环境_搭建python环境
- 怎么提高Mysql执行sql导入的速度
- COLING2018计算语言学进展
- 【支付】第三方易宝支付
- 关于XCP标定CANape的界面安全会话DLL库
- matlab遗传算法超出,matlab遗传算法提示索引超出范围
- 期权与期货有哪些不同?
- 亚像素边缘检测提取算法的实现
- 云计算储存基础(3)
- 斯蒂文斯理工学院计算机排名,2020年斯蒂文斯理工学院QS世界排名
- python 机器学习(引言-莺尾花分类)
- esp8266学习感悟
- 【Face Recognition人脸识别】3. 单张图片人脸识别