Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft - Updated documentation #164

Merged
merged 28 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b429d0f
Fix raw I2S configuration
sreckamp Feb 14, 2024
418fd05
Fix raw I2S configuration
sreckamp Feb 14, 2024
d4f3d5a
Fix RawI2S DMA size
sreckamp Feb 15, 2024
ab1b9ef
Merge branch 'refs/heads/master' into sreckamp/i2s_configuration
sreckamp Sep 16, 2024
b67d631
Remove generated headers
sreckamp Sep 16, 2024
a8f20b7
Use ifdef for switching WaveSinks
sreckamp Sep 16, 2024
4a99b93
Better error handling
sreckamp Sep 16, 2024
ec2cd26
Improve task naming/arrangement
sreckamp Sep 16, 2024
ea4a32a
pass the unknown command to "Default"
sreckamp Sep 16, 2024
70bc9a5
DeviceUnderTest Comments
sreckamp Sep 16, 2024
c8530e6
Open file is not async
sreckamp Sep 16, 2024
94e3e6b
FileSystem comments
sreckamp Sep 16, 2024
d28cca5
DeviceUnderTest comments
sreckamp Sep 16, 2024
8d91759
InterfaceMenu comments
sreckamp Sep 16, 2024
c0e647d
TaskRunner comments
sreckamp Sep 16, 2024
31353d9
Menu base class
sreckamp Sep 16, 2024
3009c78
WaveSource comments
sreckamp Sep 16, 2024
9edf910
WaveSink comments
sreckamp Sep 16, 2024
598d59d
Improved comments
sreckamp Sep 17, 2024
c5458bf
Outline of variable size DMA
sreckamp Sep 17, 2024
13691b4
Uart comments
sreckamp Sep 17, 2024
fb940bf
FxFile comments
sreckamp Sep 17, 2024
f17d602
Update the DMA configuration
sreckamp Sep 17, 2024
f2f2212
Enable printf to the debug console
sreckamp Sep 17, 2024
ef26390
Fix compilation
sreckamp Sep 17, 2024
ce52e6e
Add a README for the interface code
sreckamp Sep 17, 2024
cae802a
Update the README.md
sreckamp Sep 17, 2024
765e8c4
Add more details to README.md and improve documentation
sreckamp Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions benchmark/interface/Application/Audio/HeadphoneWaveSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Audio
HeadphoneWaveSink::HeadphoneWaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool)
: WaveSink(runner, byte_pool)
{
MX_HeadphoneSAIQueue_Config();
}

PlayerState HeadphoneWaveSink::GetState()
Expand All @@ -31,11 +32,14 @@ namespace Audio
return GetState();
}

void HeadphoneWaveSink::Configure(const WaveSource &source)
PlayerResult HeadphoneWaveSink::Configure(const WaveSource &source)
{
BSP_AUDIO_OUT_SetBitsPerSample(0, source.GetSampleSize());
BSP_AUDIO_OUT_SetChannelsNbr(0, source.GetChannelCount());
BSP_AUDIO_OUT_SetSampleRate(0, source.GetFrequency());
INT res = BSP_AUDIO_OUT_SetBitsPerSample(0, source.GetSampleSize());
if(res == BSP_ERROR_NONE)
res = BSP_AUDIO_OUT_SetChannelsNbr(0, source.GetChannelCount());
if(res == BSP_ERROR_NONE)
res = BSP_AUDIO_OUT_SetSampleRate(0, source.GetFrequency());
return res == BSP_ERROR_NONE ? SUCCESS:ERROR;
}

PlayerResult HeadphoneWaveSink::Play(UCHAR *buffer, ULONG size)
Expand Down
10 changes: 9 additions & 1 deletion benchmark/interface/Application/Audio/HeadphoneWaveSink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@

namespace Audio
{
/**
* Play audio to the headphone
*/
class HeadphoneWaveSink : public WaveSink
{
public:
/**
* Constructor
* @param runner TaskRunner that executes the submitted Task::ITasks
* @param byte_pool Memory to create the play buffer bytes
*/
HeadphoneWaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool);
protected:
void Configure(const WaveSource &source);
PlayerResult Configure(const WaveSource &source);
PlayerState GetState();
PlayerState Initialize();
PlayerResult Play(UCHAR *buffer, ULONG size);
Expand Down
56 changes: 51 additions & 5 deletions benchmark/interface/Application/Audio/RawI2SWaveSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,64 @@ namespace Audio
return GetState();
}

void RawI2SWaveSink::Configure(const WaveSource &source)
static LONG ConvertChannels(INT channelCount)
{
// BSP_AUDIO_OUT_SetBitsPerSample(0, source.GetSampleSize());
// BSP_AUDIO_OUT_SetChannelsNbr(0, source.GetChannelCount());
// BSP_AUDIO_OUT_SetSampleRate(0, source.GetFrequency());
switch(channelCount)
{
case 1:
return SAI_MONOMODE;
case 2:
return SAI_STEREOMODE;
default:
return -1;
}
}

static LONG ConvertSampleSize(INT bitCount)
{
switch(bitCount)
{
case 16:
return SAI_PROTOCOL_DATASIZE_16BIT;
case 24:
return SAI_PROTOCOL_DATASIZE_24BIT;
case 32:
return SAI_PROTOCOL_DATASIZE_32BIT;
default:
return -1;
}
}

PlayerResult RawI2SWaveSink::Configure(const WaveSource &source)
{
hsai_BlockB1.Init.AudioFrequency = source.GetFrequency();
hsai_BlockB1.Init.MonoStereoMode = ConvertChannels(source.GetChannelCount());
if (HAL_SAI_InitProtocol(&hsai_BlockB1, SAI_I2S_STANDARD,
ConvertSampleSize(source.GetSampleSize()),
source.GetChannelCount()) != HAL_OK)
return ERROR;
return SUCCESS;
}

PlayerResult RawI2SWaveSink::Play(UCHAR *buffer, ULONG size)
{
if(state == STOPPED)
{
HAL_SAI_Transmit_DMA(&hsai_BlockB1, buffer, size);
ULONG nbrSamples;
switch(hsai_BlockB1.Init.DataSize)
{
case SAI_DATASIZE_16:
nbrSamples = size / 2;
break;
case SAI_DATASIZE_24:
case SAI_DATASIZE_32:
nbrSamples = size / 4;
break;
default:
nbrSamples = size;
break;
}
HAL_SAI_Transmit_DMA(&hsai_BlockB1, buffer, nbrSamples);
state = PLAYING;
return SUCCESS;
}
Expand Down
10 changes: 9 additions & 1 deletion benchmark/interface/Application/Audio/RawI2SWaveSink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@

namespace Audio
{
/**
* Play audio to the I2S channel
*/
class RawI2SWaveSink : public WaveSink
{
public:
/**
* Constructor
* @param runner TaskRunner that executes the submitted Task::ITasks
* @param byte_pool Memory to create the play buffer bytes
*/
RawI2SWaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool);
protected:
void Configure(const WaveSource &source);
PlayerResult Configure(const WaveSource &source);
PlayerState GetState();
PlayerState Initialize();
PlayerResult Play(UCHAR *buffer, ULONG size);
Expand Down
62 changes: 43 additions & 19 deletions benchmark/interface/Application/Audio/WaveSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

#define PLAY_BUFFER_BYTES 8 * 1024

// DMA: Need to do variable-sized DMA transfers
// DMA: extern DMA_NodeTypeDef NodeTx;
// DMA: extern DMA_NodeTypeDef NodeTx2;

/**
* @brief Tx Transfer completed callbacks.
* @param hsai : pointer to a SAI_HandleTypeDef structure that contains
Expand Down Expand Up @@ -37,17 +41,17 @@ void BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t instance)

namespace Audio
{
class PlayWaveTask: public Tasks::ITask
class PlayWaveTask: public Tasks::IIndirectTask<WaveSink>
{
public:
PlayWaveTask(WaveSink &player, WaveSource &source):
ITask(TX_FALSE), player(player), source(source)
Tasks::IIndirectTask<WaveSink>(player, TX_FALSE), source(source)
{
}

void Run()
{
result = player.AsyncPlay(source);
result = actor.IndirectPlay(source);
}

PlayerResult GetResult()
Expand All @@ -56,13 +60,13 @@ namespace Audio
return result;
}
private:
WaveSink &player;
WaveSource &source;
PlayerResult result;
};

INT WaveSink::active_buffer = -1;
TX_SEMAPHORE WaveSink::buffer_semaphore;
// DMA: DMA_NodeTypeDef *WaveSink::nodes[] = {&NodeTx, &NodeTx2};

WaveSink::WaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool): runner(runner), size(PLAY_BUFFER_BYTES)
{
Expand All @@ -83,7 +87,7 @@ namespace Audio
return result;
}

PlayerResult WaveSink::AsyncPlay(WaveSource &source)
PlayerResult WaveSink::IndirectPlay(WaveSource &source)
{
PlayerState state = GetState();
if(state == RESET)
Expand All @@ -95,28 +99,48 @@ namespace Audio
return ERROR;
}

PlayerResult result = ERROR;

if(source.Open() == TX_TRUE)
{
Configure(source);
source.Seek(0);

ULONG next_bytes = source.ReadData(play_buffer, size);
active_buffer = -1;

PlayerResult status = Play((UCHAR *)play_buffer, size);

while(status == SUCCESS && next_bytes > 0)
result = Configure(source);
if(result == SUCCESS)
{
while(active_buffer == -1) tx_semaphore_get(&buffer_semaphore, 50);
INT buffer_idx = active_buffer;
source.Seek(0);

ULONG next_bytes = source.ReadData(play_buffer, size);
active_buffer = -1;

next_bytes = source.ReadData(&play_buffer[buffer_idx * size/2], size / 2);
result = Play((UCHAR *)play_buffer, size);
// DMA: result = Play((UCHAR *)play_buffer, next_bytes);
// DMA: DMA_NodeConfTypeDef node1c, node0c;
// DMA: HAL_DMAEx_List_GetNodeConfig(&node0c, nodes[0]);
// DMA: HAL_DMAEx_List_GetNodeConfig(&node1c, nodes[1]);
// DMA: if(result == SUCCESS)
// DMA: {
// DMA: state = PLAYING;
// DMA: printf ("Playing %s!\r\n", source.GetName().c_str());
// DMA: while(status == SUCCESS && next_bytes > 0)
// DMA: while(next_bytes > 0)

while(result == SUCCESS && next_bytes > 0)
{
while(active_buffer == -1) tx_semaphore_get(&buffer_semaphore, 50);
INT buffer_idx = active_buffer;
active_buffer = -1;

// DMA: HAL_DMAEx_List_GetNodeConfig(&node0c, nodes[0]);
// DMA: HAL_DMAEx_List_GetNodeConfig(&node1c, nodes[1]);
next_bytes = source.ReadData(&play_buffer[buffer_idx * size/2], size / 2);
// DMA: printf ("Prepared %ld bytes\r\n", next_bytes);
}
// DMA: printf ("Stop\r\n");
Stop();
// DMA: }
}
Stop();
source.Close();
}

return SUCCESS;
return result;
}
}
60 changes: 56 additions & 4 deletions benchmark/interface/Application/Audio/WaveSink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "WaveSource.hpp"
#include "../Tasks/TaskRunner.hpp"

#include "linked_list.h"

extern "C"
{
void BSP_AUDIO_OUT_TransferComplete_CallBack(uint32_t);
Expand All @@ -13,12 +15,18 @@ void BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t);

namespace Audio
{
/**
* Results of playing audio
*/
typedef enum
{
SUCCESS,
ERROR
} PlayerResult;

/**
* State if the audio player
*/
typedef enum
{
RESET,
Expand All @@ -28,27 +36,71 @@ namespace Audio
} PlayerState;

class PlayWaveTask;

/**
* Class to playback a wave file
*/
class WaveSink
{
public:
WaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool);
virtual ~WaveSink() { }
/**
* Play a file
* @param source The data to play
* @return The result of the playback
*/
PlayerResult Play(WaveSource &source);
virtual ~WaveSink() { }
protected:
virtual void Configure(const WaveSource &source) = 0;
/**
* Constructor
* @param runner TaskRunner that executes the submitted Task::ITasks
* @param byte_pool Memory to create the play buffer bytes
*/
WaveSink(Tasks::TaskRunner &runner, TX_BYTE_POOL &byte_pool);

/**
* Configure the playback device for the source
* @param source The media to play
* @return The results of the operation
*/
virtual PlayerResult Configure(const WaveSource &source) = 0;

/**
* Read the state of the sink
* @return Current state
*/
virtual PlayerState GetState() = 0;

/**
* Do any one-time initialization required at startup
* @return Current state
*/
virtual PlayerState Initialize() = 0;

/**
* Play a buffer
* @param buffer data to play
* @param size size of the bugger to play
* @return The results of the operation
*/
virtual PlayerResult Play(UCHAR *buffer, ULONG size) = 0;

/**
* Stop the playback
* @return The results of the operation
*/
virtual PlayerResult Stop() = 0;
private:
friend void ::BSP_AUDIO_OUT_TransferComplete_CallBack(uint32_t);
friend void ::BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t);
static INT active_buffer;
static TX_SEMAPHORE buffer_semaphore;
// DMA: static DMA_NodeTypeDef *nodes[];

Tasks::TaskRunner &runner;
UCHAR *play_buffer;
ULONG size;
PlayerResult AsyncPlay(WaveSource &source);
PlayerResult IndirectPlay(WaveSource &source);
friend class PlayWaveTask;
};
}
Expand Down
12 changes: 2 additions & 10 deletions benchmark/interface/Application/Audio/WaveSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ namespace Audio
block_alignment(0),
bits_per_sample(0),
data_size(0),
data_offset(0),
data_index(0)
data_offset(0)
{ }

/**
Expand Down Expand Up @@ -113,21 +112,14 @@ namespace Audio

UCHAR WaveSource::Seek(ULONG position)
{
if(position < data_size)
{
data_index = position;
return TX_TRUE;
}
return TX_FALSE;
return source.Seek(data_offset + position);
}

ULONG WaveSource::ReadData(void *dest, ULONG length)
{
if(is_opened == TX_FALSE) return 0;

length = data_size > data_index + length ? length : data_size - data_index;
ULONG actual_bytes = source.ReadData(dest, length);
data_index = source.GetPosition();
return actual_bytes;
}

Expand Down
Loading
Loading