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-音频输出基础(白噪)相关推荐

  1. 学习笔记(05):Mysql数据库基础入门视频教程-自连接

    立即学习:https://edu.csdn.net/course/play/9885/210119?utm_source=blogtoedu -- 子查询     -- 一个select语句包含另一个 ...

  2. 【Python学习笔记】第一章基础知识:格式化输出,转义字符,变量类型转换,算术运算符,运算符优先级和赋值运算符,逻辑运算符,世界杯案例题目,条件判断if语句,猜拳游戏与三目运算符

    Python学习笔记之[第一章]基础知识 前言: 一.格式化输出 1.基本格式: 2.练习代码: 二.转义字符 1.基本格式: 2.练习代码: 3.输出结果: 三.输入 1.基本格式: 2.练习代码: ...

  3. ESP32 单片机学习笔记 - 05 - AP/Smart Config

    ESP32 单片机学习笔记 - 05 - AP/Smart Config 终于把感觉必要的基础外设学完了,开始学esp32的主要特色功能--物联网~~?(大概) 一.WIFI热点 AP模式 编程指南: ...

  4. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  5. Linux 学习笔记之超详细基础linux命令 Part 3

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 2----------------- ...

  6. JavaScript学习笔记05【高级——DOM对象】

    w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...

  7. MySQL学习笔记05【多表操作、三大范式、数据库的备份和还原】

    MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...

  8. 《Go语言圣经》学习笔记 第三章 基础数据类型

    <Go语言圣经>学习笔记 第三章 基础数据类型 目录 整型 浮点数 复数 布尔型 字符串 常量 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记, ...

  9. MATLAB学习笔记2:MATLAB基础知识(下)

    阅读前请注意: 1. 该学习笔记是华中师范大学HelloWorld程序设计协会2021年寒假MATLAB培训的学习记录,是基于培训课堂内容的总结归纳.拓展阅读.博客内容由 @K2SO4钾 撰写.编辑, ...

  10. Kotlin学习笔记(1)-- 基础语法

    文章目录 Kotlin学习笔记(1)-- 基础语法 输出 语法 代码 输出 可读可改(var) 语法 代码 输出 内置数据类型 只读变量(val) 类型推断 编译时常量 语法 代码 输出 引用类型 r ...

最新文章

  1. 计算机中丢失sense3.dll,sense3.dll
  2. Spring-注入参数详解-[通过util命名空间简化集合类型的配置]
  3. c++ lambda基本语法
  4. 【学习笔记】opencv的python接口 几何变换
  5. avue中实现消息的实时展示
  6. bzoj4152: [AMPPZ2014]The Captain
  7. 那些年我们追过的计算机经典书
  8. python工作者工作环境_搭建python环境
  9. 怎么提高Mysql执行sql导入的速度
  10. COLING2018计算语言学进展
  11. 【支付】第三方易宝支付
  12. 关于XCP标定CANape的界面安全会话DLL库
  13. matlab遗传算法超出,matlab遗传算法提示索引超出范围
  14. 期权与期货有哪些不同?
  15. 亚像素边缘检测提取算法的实现
  16. 云计算储存基础(3)
  17. 斯蒂文斯理工学院计算机排名,2020年斯蒂文斯理工学院QS世界排名
  18. python 机器学习(引言-莺尾花分类)
  19. esp8266学习感悟
  20. 【Face Recognition人脸识别】3. 单张图片人脸识别

热门文章

  1. JVM内存管理及垃圾回收机制
  2. cv个人计算机SCI英文简历模板,个人英文简历模板
  3. python爬虫模拟浏览器的两种方法_python3爬虫的模拟浏览器
  4. vue模板字符串标签动态参数_vue模板字符串
  5. 5w1H数据分析简单例子
  6. ## 机械干了一辈子,螺栓上的8.8是什么意思
  7. IDEA打包jar包及运行jar包命令
  8. Music Collector Mac破解版——你身边的音乐收藏专家
  9. 华裔数学天才陶哲轩的传奇
  10. 《Linux内核修炼之道》精华版之方法论