function seqVector = ambiseqvec(sequence, order)
%ambiseqvec channel sequences for Higher Order Ambisonics (HOA)
%
% inputs
% sequence  : Desired sequence of a specific format 
%               'fuma-acn' or 'acn-fuma'
% order     : Ambisonic order, integer value 0 through 16
%
% outputs
% seqVector : vector of specified sequence
%
% This function ambiseqvec is for demonstration purposes. It is used in
% support of ambiencode and ambidecode. It may change in a future release.

% Copyright 2018-2019 The MathWorks, Inc.

%#codegen
% -------------------------------------------------------------------------
sequence = char(sequence);  % string support
validateattributes(order, {'numeric'}, ...
	{'nonempty','real','integer','scalar','>=',0,'<=',7},...
	'ambinormvec','order',2);
% -------------------------------------------------------------------------
switch sequence
	case 'acn-fuma'
		seqVector = acn_fuma(order);
	case 'fuma-acn'
		seqVector = fuma_acn(order);
	otherwise
		coder.internal.error('audio:ambisonics:sequenceInvalid', sequence);
end
% -------------------------------------------------------------------------
function out = acn_fuma(order)
	data = [	1, ...
	4, 2, 3, ...
	7, 8, 6, 9, 5, ...
	13, 14, 12, 15, 11, 16, 10, ...
	21, 22, 20, 23, 19, 24, 18, 25, 17, ...
	31, 32, 30, 33, 29, 34, 28, 35, 27, 36, 26, ...
	43, 44, 42, 45, 41, 46, 40, 47, 39, 48, 38, 49, 37, ...
	57, 58, 56, 59, 55, 60, 54, 61, 53, 62, 52, 63, 51, 64, 50, ...
	73, 74, 72, 75, 71, 76, 70, 77, 69, 78, 68, 79, 67, 80, 66, 81, 65, ...
	91, 92, 90, 93, 89, 94, 88, 95, 87, 96, 86, 97, 85, 98, 84, 99, 83, 100, 82, ...
	111, 112, 110, 113, 109, 114, 108, 115, 107, 116, 106, 117, 105, 118, 104, 119, 103, 120, 102, 121, 101, ...
	133, 134, 132, 135, 131, 136, 130, 137, 129, 138, 128, 139, 127, 140, 126, 141, 125, 142, 124, 143, 123, 144, 122, ...
	157, 158, 156, 159, 155, 160, 154, 161, 153, 162, 152, 163, 151, 164, 150, 165, 149, 166, 148, 167, 147, 168, 146, 169, 145, ...
	183, 184, 182, 185, 181, 186, 180, 187, 179, 188, 178, 189, 177, 190, 176, 191, 175, 192, 174, 193, 173, 194, 172, 195, 171, 196, 170, ...
	211, 212, 210, 213, 209, 214, 208, 215, 207, 216, 206, 217, 205, 218, 204, 219, 203, 220, 202, 221, 201, 222, 200, 223, 199, 224, 198, 225, 197, ...
	241, 242, 240, 243, 239, 244, 238, 245, 237, 246, 236, 247, 235, 248, 234, 249, 233, 250, 232, 251, 231, 252, 230, 253, 229, 254, 228, 255, 227, 256, 226, ...
	273, 274, 272, 275, 271, 276, 270, 277, 269, 278, 268, 279, 267, 280, 266, 281, 265, 282, 264, 283, 263, 284, 262, 285, 261, 286, 260, 287, 259, 288, 258, 289, 257, ...
	];
	out = data(1:order2chan(order));
end
% -------------------------------------------------------------------------
function out = fuma_acn(order)
	data = [	1, ...
	3, 4, 2, ...
	9, 7, 5, 6, 8, ...
	16, 14, 12, 10, 11, 13, 15, ...
	25, 23, 21, 19, 17, 18, 20, 22, 24, ...
	36, 34, 32, 30, 28, 26, 27, 29, 31, 33, 35, ...
	49, 47, 45, 43, 41, 39, 37, 38, 40, 42, 44, 46, 48, ...
	64, 62, 60, 58, 56, 54, 52, 50, 51, 53, 55, 57, 59, 61, 63, ...
	81, 79, 77, 75, 73, 71, 69, 67, 65, 66, 68, 70, 72, 74, 76, 78, 80, ...
	100, 98, 96, 94, 92, 90, 88, 86, 84, 82, 83, 85, 87, 89, 91, 93, 95, 97, 99, ...
	121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, ...
	144, 142, 140, 138, 136, 134, 132, 130, 128, 126, 124, 122, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, ...
	169, 167, 165, 163, 161, 159, 157, 155, 153, 151, 149, 147, 145, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, ...
	196, 194, 192, 190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, ...
	225, 223, 221, 219, 217, 215, 213, 211, 209, 207, 205, 203, 201, 199, 197, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, ...
	256, 254, 252, 250, 248, 246, 244, 242, 240, 238, 236, 234, 232, 230, 228, 226, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, ...
	289, 287, 285, 283, 281, 279, 277, 275, 273, 271, 269, 267, 265, 263, 261, 259, 257, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, ...
	];
	out = data(1:order2chan(order));
end
% -------------------------------------------------------------------------
function channels = order2chan(order)
    channels = (order+1)^2;
end
% -------------------------------------------------------------------------
end
